<commit_before>package lfchan

import (
	"runtime"
	"sync/atomic"
)

type innerChan struct {
	q       []AtomicValue
	sendIdx uint32
	recvIdx uint32
	len     int32
	die     int32
}

// Chan is a lock free channel that supports concurrent channel operations.
type Chan struct {
	*innerChan
}

// New returns a new channel with the buffer set to 1
func New() Chan {
	return NewSize(1)
}

// NewSize creates a buffered channel, with minimum length of 1
func NewSize(sz int) Chan {
	if sz < 1 {
		panic("sz < 1")
	}
	return Chan{&innerChan{
		q:       make([]AtomicValue, sz),
		sendIdx: ^uint32(0),
		recvIdx: ^uint32(0),
	}}
}

// Send adds v to the buffer of the channel and returns true, if the channel is closed it returns false
func (ch Chan) Send(v interface{}, block bool) bool {
	if !block && ch.Len() == ch.Cap() {
		return false
	}
	ncpu, ln, cnt := uint32(runtime.NumCPU()), uint32(len(ch.q)), uint32(0)
	for !ch.Closed() {

		i := atomic.AddUint32(&ch.sendIdx, 1)
		if ch.q[i%ln].CompareAndSwap(nil, v) {
			atomic.AddInt32(&ch.len, 1)
			return true
		}
		if block {
			if i%(ncpu*100) == 0 {
				for i := uint32(0); i < ncpu; i++ {
					runtime.Gosched()
				}
			}
		} else if cnt++; cnt == ln {
			break
		}
		runtime.Gosched()
	}
	return false
}

// Recv blocks until a value is available and returns v, true, or if the channel is closed and
// the buffer is empty, it will return nil, false
func (ch Chan) Recv(block bool) (interface{}, bool) {
	if !block && ch.Len() == 0 { // fast path
		return nil, false
	}
	ncpu, ln, cnt := uint32(runtime.NumCPU()), uint32(len(ch.q)), uint32(0)
	for !ch.Closed() || ch.Len() > 0 {
		i := atomic.AddUint32(&ch.recvIdx, 1)
		if v := ch.q[i%ln].Swap(nil); v != nil {
			atomic.AddInt32(&ch.len, -1)
			return v, true
		}
		if block {
			if i%(ncpu*100) == 0 {
				for i := uint32(0); i < ncpu; i++ {
					runtime.Gosched()
				}
			}
		} else if cnt++; cnt == ln {
			break
		}
		runtime.Gosched()
	}
	return nil, false
}

// Close marks the channel as closed
func (ch Chan) Close() { atomic.StoreInt32(&ch.die, 1) }

// Closed returns true if the channel have been closed
func (ch Chan) Closed() bool { return atomic.LoadInt32(&ch.die) == 1 }

// Cap returns the size of the internal queue
func (ch Chan) Cap() int { return len(ch.q) }

// Len returns the number of elements queued
func (ch Chan) Len() int { return int(atomic.LoadInt32(&ch.len)) }

// SelectSend sends v to the first available channel, if block is true, it blocks until a channel a accepts the value.
// returns false if all channels were full and block is false.
func SelectSend(block bool, v interface{}, chans ...Chan) bool {
	for {
		for i := range chans {
			if ok := chans[i].Send(v, false); ok {
				return ok
			}
		}
		if !block {
			return false
		}
		runtime.Gosched()
	}
}

// SelectRecv returns the first available value from chans, if block is true, it blocks until a value is available.
// returns nil, false if all channels were empty and block is false.
func SelectRecv(block bool, chans ...Chan) (interface{}, bool) {
	for {
		for i := range chans {
			if v, ok := chans[i].Recv(false); ok {
				return v, ok
			}
		}
		if !block {
			return nil, false
		}
		runtime.Gosched()
	}
}
<commit_msg>Send/RecvOnly impl<commit_after>package lfchan

import (
	"runtime"
	"sync/atomic"
)

type innerChan struct {
	q       []AtomicValue
	sendIdx uint32
	recvIdx uint32
	len     int32
	die     int32
}

// Chan is a lock free channel that supports concurrent channel operations.
type Chan struct {
	*innerChan
}

// New returns a new channel with the buffer set to 1
func New() Chan {
	return NewSize(1)
}

// NewSize creates a buffered channel, with minimum length of 1
func NewSize(sz int) Chan {
	if sz < 1 {
		panic("sz < 1")
	}
	return Chan{&innerChan{
		q:       make([]AtomicValue, sz),
		sendIdx: ^uint32(0),
		recvIdx: ^uint32(0),
	}}
}

// Send adds v to the buffer of the channel and returns true, if the channel is closed it returns false
func (ch Chan) Send(v interface{}, block bool) bool {
	if !block && ch.Len() == ch.Cap() {
		return false
	}
	ncpu, ln, cnt := uint32(runtime.NumCPU()), uint32(len(ch.q)), uint32(0)
	for !ch.Closed() {

		i := atomic.AddUint32(&ch.sendIdx, 1)
		if ch.q[i%ln].CompareAndSwap(nil, v) {
			atomic.AddInt32(&ch.len, 1)
			return true
		}
		if block {
			if i%(ncpu*100) == 0 {
				for i := uint32(0); i < ncpu; i++ {
					runtime.Gosched()
				}
			}
		} else if cnt++; cnt == ln {
			break
		}
		runtime.Gosched()
	}
	return false
}

// Recv blocks until a value is available and returns v, true, or if the channel is closed and
// the buffer is empty, it will return nil, false
func (ch Chan) Recv(block bool) (interface{}, bool) {
	if !block && ch.Len() == 0 { // fast path
		return nil, false
	}
	ncpu, ln, cnt := uint32(runtime.NumCPU()), uint32(len(ch.q)), uint32(0)
	for !ch.Closed() || ch.Len() > 0 {
		i := atomic.AddUint32(&ch.recvIdx, 1)
		if v := ch.q[i%ln].Swap(nil); v != nil {
			atomic.AddInt32(&ch.len, -1)
			return v, true
		}
		if block {
			if i%(ncpu*100) == 0 {
				for i := uint32(0); i < ncpu; i++ {
					runtime.Gosched()
				}
			}
		} else if cnt++; cnt == ln {
			break
		}
		runtime.Gosched()
	}
	return nil, false
}

// RecvOnly returns a receive-only channel.
func (ch Chan) RecvOnly() RecvOnly { return RecvOnly{ch} }

// RecvOnly returns a send-only channel.
func (ch Chan) SendOnly() SendOnly { return SendOnly{ch} }

// Close marks the channel as closed
func (ch Chan) Close() { atomic.StoreInt32(&ch.die, 1) }

// Closed returns true if the channel have been closed
func (ch Chan) Closed() bool { return atomic.LoadInt32(&ch.die) == 1 }

// Cap returns the size of the internal queue
func (ch Chan) Cap() int { return len(ch.q) }

// Len returns the number of elements queued
func (ch Chan) Len() int { return int(atomic.LoadInt32(&ch.len)) }

// SelectSend sends v to the first available channel, if block is true, it blocks until a channel a accepts the value.
// returns false if all channels were full and block is false.
func SelectSend(block bool, v interface{}, chans ...Chan) bool {
	for {
		for i := range chans {
			if ok := chans[i].Send(v, false); ok {
				return ok
			}
		}
		if !block {
			return false
		}
		runtime.Gosched()
	}
}

// SelectRecv returns the first available value from chans, if block is true, it blocks until a value is available.
// returns nil, false if all channels were empty and block is false.
func SelectRecv(block bool, chans ...Chan) (interface{}, bool) {
	for {
		for i := range chans {
			if v, ok := chans[i].Recv(false); ok {
				return v, ok
			}
		}
		if !block {
			return nil, false
		}
		runtime.Gosched()
	}
}

// RecvOnly is a channel only has receive operations.
type RecvOnly struct{ c Chan }

// Recv
func (ro RecvOnly) Recv(block bool) (interface{}, bool) { return ro.c.Recv(block) }

// SebdOnly is a channel only has send operations.
type SendOnly struct{ c Chan }

// Send
func (so SendOnly) Send(v interface{}, block bool) bool { return so.c.Send(v, block) }
<|endoftext|>


<commit_before>package cobertura

import (
	"encoding/xml"
	"os"
	"sort"
	"strings"

	"github.com/Sirupsen/logrus"
	"github.com/codeclimate/test-reporter/env"
	"github.com/codeclimate/test-reporter/formatters"
	"github.com/pkg/errors"
)

var searchPaths = []string{"cobertura.xml", "cobertura.ser"}

type Formatter struct {
	Path string
}

func (f *Formatter) Search(paths ...string) (string, error) {
	paths = append(paths, searchPaths...)
	for _, p := range paths {
		logrus.Debugf("checking search path %s for cobertura formatter", p)
		if _, err := os.Stat(p); err == nil {
			f.Path = p
			return p, nil
		}
	}

	return "", errors.WithStack(errors.Errorf("could not find any files in search paths for cobertura. search paths were: %s", strings.Join(paths, ", ")))
}

func (r Formatter) Format() (formatters.Report, error) {
	rep, err := formatters.NewReport()
	if err != nil {
		return rep, err
	}

	fx, err := os.Open(r.Path)
	if err != nil {
		return rep, errors.WithStack(err)
	}

	coberturaFile := &xmlFile{}
	err = xml.NewDecoder(fx).Decode(coberturaFile)

	if err != nil {
		return rep, errors.WithStack(err)
	}

	gitHead, _ := env.GetHead()
	for _, pp := range coberturaFile.Packages {
		mergedClasses := make(map[string]*xmlClass)
		// merge Classes by filename
		for i, clss := range pp.Classes {
			filename := clss.FileName
			if _, ok := mergedClasses[filename]; ok {
				// Appends lines for mergedClasses with the same filename
				lines := append(mergedClasses[filename].Lines, clss.Lines...)
				mergedClasses[filename].Lines = lines
			} else {
				mergedClasses[filename] = &pp.Classes[i]
			}
		}

		for _, pf := range mergedClasses {
			num := 1
			fileName := coberturaFile.getFullFilePath(pf.FileName)
			logrus.Debugf("creating test file report for %s", fileName)
			sf, err := formatters.NewSourceFile(fileName, gitHead)
			if err != nil {
				return rep, errors.WithStack(err)
			}
			sort.Sort(ByLineNum(pf.Lines))
			for _, l := range pf.Lines {
				if l.Num > 0 {
					for num < l.Num {
						sf.Coverage = append(sf.Coverage, formatters.NullInt{})
						num++
					}
					if l.Num <= len(sf.Coverage) {
						hits := sf.Coverage[l.Num-1].Int + l.Hits
						sf.Coverage[l.Num-1] = formatters.NewNullInt(hits)
					} else {
						ni := formatters.NewNullInt(l.Hits)
						sf.Coverage = append(sf.Coverage, ni)
						num++
					}
				} else {
					logrus.Warnf("Invalid line number %d in file %s", l.Num, fileName)
				}
			}
			err = rep.AddSourceFile(sf)
			if err != nil {
				return rep, errors.WithStack(err)
			}
		}
	}

	return rep, nil
}
<commit_msg>Remove cobertura.ser from Cobertura searchPaths (#365)<commit_after>package cobertura

import (
	"encoding/xml"
	"os"
	"sort"
	"strings"

	"github.com/Sirupsen/logrus"
	"github.com/codeclimate/test-reporter/env"
	"github.com/codeclimate/test-reporter/formatters"
	"github.com/pkg/errors"
)

var searchPaths = []string{"cobertura.xml"}

type Formatter struct {
	Path string
}

func (f *Formatter) Search(paths ...string) (string, error) {
	paths = append(paths, searchPaths...)
	for _, p := range paths {
		logrus.Debugf("checking search path %s for cobertura formatter", p)
		if _, err := os.Stat(p); err == nil {
			f.Path = p
			return p, nil
		}
	}

	return "", errors.WithStack(errors.Errorf("could not find any files in search paths for cobertura. search paths were: %s", strings.Join(paths, ", ")))
}

func (r Formatter) Format() (formatters.Report, error) {
	rep, err := formatters.NewReport()
	if err != nil {
		return rep, err
	}

	fx, err := os.Open(r.Path)
	if err != nil {
		return rep, errors.WithStack(err)
	}

	coberturaFile := &xmlFile{}
	err = xml.NewDecoder(fx).Decode(coberturaFile)

	if err != nil {
		return rep, errors.WithStack(err)
	}

	gitHead, _ := env.GetHead()
	for _, pp := range coberturaFile.Packages {
		mergedClasses := make(map[string]*xmlClass)
		// merge Classes by filename
		for i, clss := range pp.Classes {
			filename := clss.FileName
			if _, ok := mergedClasses[filename]; ok {
				// Appends lines for mergedClasses with the same filename
				lines := append(mergedClasses[filename].Lines, clss.Lines...)
				mergedClasses[filename].Lines = lines
			} else {
				mergedClasses[filename] = &pp.Classes[i]
			}
		}

		for _, pf := range mergedClasses {
			num := 1
			fileName := coberturaFile.getFullFilePath(pf.FileName)
			logrus.Debugf("creating test file report for %s", fileName)
			sf, err := formatters.NewSourceFile(fileName, gitHead)
			if err != nil {
				return rep, errors.WithStack(err)
			}
			sort.Sort(ByLineNum(pf.Lines))
			for _, l := range pf.Lines {
				if l.Num > 0 {
					for num < l.Num {
						sf.Coverage = append(sf.Coverage, formatters.NullInt{})
						num++
					}
					if l.Num <= len(sf.Coverage) {
						hits := sf.Coverage[l.Num-1].Int + l.Hits
						sf.Coverage[l.Num-1] = formatters.NewNullInt(hits)
					} else {
						ni := formatters.NewNullInt(l.Hits)
						sf.Coverage = append(sf.Coverage, ni)
						num++
					}
				} else {
					logrus.Warnf("Invalid line number %d in file %s", l.Num, fileName)
				}
			}
			err = rep.AddSourceFile(sf)
			if err != nil {
				return rep, errors.WithStack(err)
			}
		}
	}

	return rep, nil
}
<|endoftext|>


<commit_before>package expr

import (
	"testing"
	"time"

	"github.com/StackExchange/bosun/_third_party/github.com/StackExchange/scollector/opentsdb"
)

func TestExprSimple(t *testing.T) {
	var exprTests = []struct {
		input  string
		output Scalar
	}{
		{"!1", 0},
		{"-2", -2},
		{"1.444-010+2*3e2-4/5+0xff", 847.644},
		{"1>2", 0},
		{"3>2", 1},
		{"1==1", 1},
		{"1==2", 0},
		{"1!=01", 0},
		{"1!=2", 1},
		{"1<2", 1},
		{"2<1", 0},
		{"1||0", 1},
		{"0||0", 0},
		{"1&&0", 0},
		{"1&&2", 1},
		{"1<=0", 0},
		{"1<=1", 1},
		{"1<=2", 1},
		{"1>=0", 1},
		{"1>=1", 1},
		{"1>=2", 0},
		{"-1 > 0", 0},
		{"-1 < 0", 1},
	}

	for _, et := range exprTests {
		e, err := New(et.input)
		if err != nil {
			t.Error(err)
			break
		}
		r, _, err := e.Execute(opentsdb.Host(""), nil, time.Now(), 0, false, nil, nil)
		if err != nil {
			t.Error(err)
			break
		} else if len(r.Results) != 1 {
			t.Error("bad r len", len(r.Results))
			break
		} else if len(r.Results[0].Group) != 0 {
			t.Error("bad group len", r.Results[0].Group)
			break
		} else if r.Results[0].Value != et.output {
			t.Errorf("expected %v, got %v: %v\nast: %v", et.output, r.Results[0].Value, et.input, e)
		}
	}
}

func TestExprParse(t *testing.T) {
	var exprTests = []struct {
		input string
		valid bool
	}{
		{`avg(q("test", "1m", 1))`, false},
	}

	for _, et := range exprTests {
		_, err := New(et.input)
		if et.valid && err != nil {
			t.Error(err)
		} else if !et.valid && err == nil {
			t.Errorf("expected invalid, but no error: %v", et.input)
		}
	}
}

/*
const TSDBHost = "ny-devtsdb04:4242"

func TestExprQuery(t *testing.T) {
	e, err := New(`forecastlr(q("avg:os.cpu{host=ny-lb05}", "1m", ""), -10)`)
	if err != nil {
		t.Fatal(err)
	}
	_, _, err = e.Execute(opentsdb.Host(TSDBHost), nil)
	if err != nil {
		t.Fatal(err)
	}
}
*/
<commit_msg>Fix test<commit_after>package expr

import (
	"testing"
	"time"

	"github.com/StackExchange/bosun/_third_party/github.com/StackExchange/scollector/opentsdb"
)

func TestExprSimple(t *testing.T) {
	var exprTests = []struct {
		input  string
		output Scalar
	}{
		{"!1", 0},
		{"-2", -2},
		{"1.444-010+2*3e2-4/5+0xff", 847.644},
		{"1>2", 0},
		{"3>2", 1},
		{"1==1", 1},
		{"1==2", 0},
		{"1!=01", 0},
		{"1!=2", 1},
		{"1<2", 1},
		{"2<1", 0},
		{"1||0", 1},
		{"0||0", 0},
		{"1&&0", 0},
		{"1&&2", 1},
		{"1<=0", 0},
		{"1<=1", 1},
		{"1<=2", 1},
		{"1>=0", 1},
		{"1>=1", 1},
		{"1>=2", 0},
		{"-1 > 0", 0},
		{"-1 < 0", 1},
	}

	for _, et := range exprTests {
		e, err := New(et.input)
		if err != nil {
			t.Error(err)
			break
		}
		r, _, err := e.Execute(opentsdb.Host(""), nil, time.Now(), 0, false, nil, nil, nil)
		if err != nil {
			t.Error(err)
			break
		} else if len(r.Results) != 1 {
			t.Error("bad r len", len(r.Results))
			break
		} else if len(r.Results[0].Group) != 0 {
			t.Error("bad group len", r.Results[0].Group)
			break
		} else if r.Results[0].Value != et.output {
			t.Errorf("expected %v, got %v: %v\nast: %v", et.output, r.Results[0].Value, et.input, e)
		}
	}
}

func TestExprParse(t *testing.T) {
	var exprTests = []struct {
		input string
		valid bool
	}{
		{`avg(q("test", "1m", 1))`, false},
	}

	for _, et := range exprTests {
		_, err := New(et.input)
		if et.valid && err != nil {
			t.Error(err)
		} else if !et.valid && err == nil {
			t.Errorf("expected invalid, but no error: %v", et.input)
		}
	}
}

/*
const TSDBHost = "ny-devtsdb04:4242"

func TestExprQuery(t *testing.T) {
	e, err := New(`forecastlr(q("avg:os.cpu{host=ny-lb05}", "1m", ""), -10)`)
	if err != nil {
		t.Fatal(err)
	}
	_, _, err = e.Execute(opentsdb.Host(TSDBHost), nil)
	if err != nil {
		t.Fatal(err)
	}
}
*/
<|endoftext|>


<commit_before>package main

import (
	"gopkg.in/yaml.v2"

	"io/ioutil"

	"github.com/alexgarzao/ms-gen/swaggerparser"
)

type (
	Api struct {
		Filename            string
		OutputDir           string
		ServiceName         string
		FriendlyServiceName string
		CommonImportPath    string
		Methods             []*Method
		Definitions         []Definition
		CurrentMethod       *Method
	}

	Definition struct {
		Name       string
		Properties []*Property
	}
)

func NewApi(filename string, outputDir string) (api *Api) {
	api = new(Api)
	api.Filename = filename
	api.OutputDir = outputDir

	return api
}

func (api *Api) LoadFromSwagger() error {
	// Reading from swagger file.
	config, err := ioutil.ReadFile(api.Filename)
	if err != nil {
		return err
	}

	if err := api.parser(config); err != nil {
		return err
	}

	return nil
}

func (api *Api) parser(text []byte) error {
	swagger := new(swaggerparser.Swagger)

	if err := yaml.Unmarshal(text, swagger); err != nil {
		return err
	}

	api.ServiceName = "myservice"
	api.FriendlyServiceName = swagger.Info.Title

	api.Methods = api.fillMethods(swagger.Paths)

	api.Definitions = api.fillDefinitions(swagger.Definitions)

	commonImportPath, err := GetCommonImportPath(api.OutputDir, api.ServiceName)
	if err != nil {
		return err
	}

	api.CommonImportPath = commonImportPath

	return nil
}

// Fill methods.
func (api *Api) fillMethods(pathDefinitions map[string]*swaggerparser.Path) []*Method {
	var methods []*Method
	for k, v := range pathDefinitions {
		if v.Get != nil {
			methods = append(methods, NewMethod(api.ServiceName, k, "Get", v.Get))
		}

		if v.Post != nil {
			methods = append(methods, NewMethod(api.ServiceName, k, "Post", v.Post))
		}

		if v.Put != nil {
			methods = append(methods, NewMethod(api.ServiceName, k, "Put", v.Put))
		}
	}

	return methods
}

// Fill definitions.
func (api *Api) fillDefinitions(apiDefinitions map[string]*swaggerparser.JSONSchema) []Definition {
	var definitions []Definition

	for apiDefinitionKey, apiDefinitionValue := range apiDefinitions {
		definition := Definition{}
		definition.Name = apiDefinitionKey
		for propertyKey, propertyValue := range apiDefinitionValue.Properties {
			property := NewProperty(propertyKey, propertyValue)
			definition.Properties = append(definition.Properties, property)
		}
		definitions = append(definitions, definition)
	}

	return definitions
}
<commit_msg>Refactor: Definition class was moved to a new file.<commit_after>package main

import (
	"gopkg.in/yaml.v2"

	"io/ioutil"

	"github.com/alexgarzao/ms-gen/swaggerparser"
)

type Api struct {
	Filename            string
	OutputDir           string
	ServiceName         string
	FriendlyServiceName string
	CommonImportPath    string
	Methods             []*Method
	Definitions         []*Definition
	CurrentMethod       *Method
}

func NewApi(filename string, outputDir string) (api *Api) {
	api = new(Api)
	api.Filename = filename
	api.OutputDir = outputDir

	return api
}

func (api *Api) LoadFromSwagger() error {
	// Reading from swagger file.
	config, err := ioutil.ReadFile(api.Filename)
	if err != nil {
		return err
	}

	if err := api.parser(config); err != nil {
		return err
	}

	return nil
}

func (api *Api) parser(text []byte) error {
	swagger := new(swaggerparser.Swagger)

	if err := yaml.Unmarshal(text, swagger); err != nil {
		return err
	}

	api.ServiceName = "myservice"
	api.FriendlyServiceName = swagger.Info.Title

	api.Methods = api.fillMethods(swagger.Paths)

	api.Definitions = FillDefinitions(swagger.Definitions)

	commonImportPath, err := GetCommonImportPath(api.OutputDir, api.ServiceName)
	if err != nil {
		return err
	}

	api.CommonImportPath = commonImportPath

	return nil
}

// Fill methods.
func (api *Api) fillMethods(pathDefinitions map[string]*swaggerparser.Path) []*Method {
	var methods []*Method
	for k, v := range pathDefinitions {
		if v.Get != nil {
			methods = append(methods, NewMethod(api.ServiceName, k, "Get", v.Get))
		}

		if v.Post != nil {
			methods = append(methods, NewMethod(api.ServiceName, k, "Post", v.Post))
		}

		if v.Put != nil {
			methods = append(methods, NewMethod(api.ServiceName, k, "Put", v.Put))
		}
	}

	return methods
}
<|endoftext|>


<commit_before>// File: ./blockfreight/bft/crypto/crypto.go
// Summary: Application code for Blockfreight™ | The blockchain of global freight.
// License: MIT License
// Company: Blockfreight, Inc.
// Author: Julian Nunez, Neil Tran, Julian Smith & contributors
// Site: https://blockfreight.com
// Support: <support@blockfreight.com>

// Copyright 2017 Blockfreight, Inc.

// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

// =================================================================================================================================================
// =================================================================================================================================================
//
// BBBBBBBBBBBb     lll                                kkk             ffff                         iii                  hhh            ttt
// BBBB``````BBBB   lll                                kkk            fff                           ```                  hhh            ttt
// BBBB      BBBB   lll      oooooo        ccccccc     kkk    kkkk  fffffff  rrr  rrr    eeeee      iii     gggggg ggg   hhh  hhhhh   tttttttt
// BBBBBBBBBBBB     lll    ooo    oooo    ccc    ccc   kkk   kkk    fffffff  rrrrrrrr eee    eeee   iii   gggg   ggggg   hhhh   hhhh  tttttttt
// BBBBBBBBBBBBBB   lll   ooo      ooo   ccc           kkkkkkk        fff    rrrr    eeeeeeeeeeeee  iii  gggg      ggg   hhh     hhh    ttt
// BBBB       BBB   lll   ooo      ooo   ccc           kkkk kkkk      fff    rrr     eeeeeeeeeeeee  iii   ggg      ggg   hhh     hhh    ttt
// BBBB      BBBB   lll   oooo    oooo   cccc    ccc   kkk   kkkk     fff    rrr      eee      eee  iii    ggg    gggg   hhh     hhh    tttt    ....
// BBBBBBBBBBBBB    lll     oooooooo       ccccccc     kkk     kkkk   fff    rrr       eeeeeeeee    iii     gggggg ggg   hhh     hhh     ttttt  ....
//                                                                                ggg      ggg
//   Blockfreight™ | The blockchain of global freight.                                                      ggggggggg
//
// =================================================================================================================================================
// =================================================================================================================================================

// Package crypto provides useful functions to sign BF_TX.
package crypto

import (
    // =======================
    // Golang Standard library
    // =======================
    "crypto/ecdsa"      // Implements the Elliptic Curve Digital Signature Algorithm, as defined in FIPS 186-3.
    "crypto/elliptic"   // Implements several standard elliptic curves over prime fields.
    "crypto/md5"        // Implements the MD5 hash algorithm as defined in RFC 1321.
    "crypto/rand"       // Implements a cryptographically secure pseudorandom number generator.
    "fmt"               // Implements formatted I/O with functions analogous to C's printf and scanf.
    "hash"              // Provides interfaces for hash functions.
    "io"                // Provides basic interfaces to I/O primitives.
    "math/big"          // Implements arbitrary-precision arithmetic (big numbers).
    "os"                // Provides a platform-independent interface to operating system functionality.
    "strconv"           // Implements conversions to and from string representations of basic data types.

    // ======================
    // Blockfreight™ packages
    // ======================
    "github.com/blockfreight/blockfreight-alpha/blockfreight/bft/bf_tx" // Defines the Blockfreight™ Transaction (BF_TX) transaction standard and provides some useful functions to work with the BF_TX.
)

//  @todo: OP_2 <pubkey1> <pubkey2> <pubkey3> <pubkey4> <pubkey5> OP_3 OP_CHECKMULTISIGVERIFY <pubkey3> OP_CHECKSIG

// Function Sign_BF_TX has the whole process of signing each BF_TX.
func Sign_BF_TX(bft_tx bf_tx.BF_TX) bf_tx.BF_TX {

    content := bf_tx.BF_TXContent(bft_tx)

    pubkeyCurve := elliptic.P256() //see http://golang.org/pkg/crypto/elliptic/#P256

    privatekey := new(ecdsa.PrivateKey)
    privatekey, err := ecdsa.GenerateKey(pubkeyCurve, rand.Reader) // this generates a public & private key pair

    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    pubkey := privatekey.PublicKey

    // Sign ecdsa style
    var h hash.Hash
    h = md5.New()
    r := big.NewInt(0)
    s := big.NewInt(0)

    io.WriteString(h, content)
    signhash := h.Sum(nil)

    r, s, serr := ecdsa.Sign(rand.Reader, privatekey, signhash)
    if serr != nil {
        fmt.Println(err)
        os.Exit(1)
    }

    signature := r.Bytes()
    signature = append(signature, s.Bytes()...)

    sign := ""
    for i, _ := range signature {
        sign += strconv.Itoa(int(signature[i]))
    }

    // Verification
    verifystatus := ecdsa.Verify(&pubkey, signhash, r, s)

    //Set Private Key and Sign to BF_TX
    bft_tx.PrivateKey = *privatekey
    bft_tx.Signhash = signhash
    bft_tx.Signature = sign
    bft_tx.Signed = verifystatus

    return bft_tx
}

// =================================================
// Blockfreight™ | The blockchain of global freight.
// =================================================

// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
// BBBBBBB                    BBBBBBBBBBBBBBBBBBB
// BBBBBBB                       BBBBBBBBBBBBBBBB
// BBBBBBB                        BBBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBB        BBBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBB        BBBBBBBBBBBBBBB
// BBBBBBB       BBBBBBB         BBBBBBBBBBBBBBBB
// BBBBBBB                     BBBBBBBBBBBBBBBBBB
// BBBBBBB                        BBBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBBB        BBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBBBB       BBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBBB        BBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBB        BBB       BBBBB
// BBBBBBB                       BBBB       BBBBB
// BBBBBBB                    BBBBBBB       BBBBB
// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB

// ==================================================
// Blockfreight™ | The blockchain for global freight.
// ==================================================
<commit_msg>Modify assignation of bool attribute when the BF_TX was verified<commit_after>// File: ./blockfreight/bft/crypto/crypto.go
// Summary: Application code for Blockfreight™ | The blockchain of global freight.
// License: MIT License
// Company: Blockfreight, Inc.
// Author: Julian Nunez, Neil Tran, Julian Smith & contributors
// Site: https://blockfreight.com
// Support: <support@blockfreight.com>

// Copyright 2017 Blockfreight, Inc.

// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

// =================================================================================================================================================
// =================================================================================================================================================
//
// BBBBBBBBBBBb     lll                                kkk             ffff                         iii                  hhh            ttt
// BBBB``````BBBB   lll                                kkk            fff                           ```                  hhh            ttt
// BBBB      BBBB   lll      oooooo        ccccccc     kkk    kkkk  fffffff  rrr  rrr    eeeee      iii     gggggg ggg   hhh  hhhhh   tttttttt
// BBBBBBBBBBBB     lll    ooo    oooo    ccc    ccc   kkk   kkk    fffffff  rrrrrrrr eee    eeee   iii   gggg   ggggg   hhhh   hhhh  tttttttt
// BBBBBBBBBBBBBB   lll   ooo      ooo   ccc           kkkkkkk        fff    rrrr    eeeeeeeeeeeee  iii  gggg      ggg   hhh     hhh    ttt
// BBBB       BBB   lll   ooo      ooo   ccc           kkkk kkkk      fff    rrr     eeeeeeeeeeeee  iii   ggg      ggg   hhh     hhh    ttt
// BBBB      BBBB   lll   oooo    oooo   cccc    ccc   kkk   kkkk     fff    rrr      eee      eee  iii    ggg    gggg   hhh     hhh    tttt    ....
// BBBBBBBBBBBBB    lll     oooooooo       ccccccc     kkk     kkkk   fff    rrr       eeeeeeeee    iii     gggggg ggg   hhh     hhh     ttttt  ....
//                                                                                ggg      ggg
//   Blockfreight™ | The blockchain of global freight.                                                      ggggggggg
//
// =================================================================================================================================================
// =================================================================================================================================================

// Package crypto provides useful functions to sign BF_TX.
package crypto

import (
    // =======================
    // Golang Standard library
    // =======================
    "crypto/ecdsa"      // Implements the Elliptic Curve Digital Signature Algorithm, as defined in FIPS 186-3.
    "crypto/elliptic"   // Implements several standard elliptic curves over prime fields.
    "crypto/md5"        // Implements the MD5 hash algorithm as defined in RFC 1321.
    "crypto/rand"       // Implements a cryptographically secure pseudorandom number generator.
    "fmt"               // Implements formatted I/O with functions analogous to C's printf and scanf.
    "hash"              // Provides interfaces for hash functions.
    "io"                // Provides basic interfaces to I/O primitives.
    "math/big"          // Implements arbitrary-precision arithmetic (big numbers).
    "os"                // Provides a platform-independent interface to operating system functionality.
    "strconv"           // Implements conversions to and from string representations of basic data types.

    // ======================
    // Blockfreight™ packages
    // ======================
    "github.com/blockfreight/blockfreight-alpha/blockfreight/bft/bf_tx" // Defines the Blockfreight™ Transaction (BF_TX) transaction standard and provides some useful functions to work with the BF_TX.
)

//  @todo: OP_2 <pubkey1> <pubkey2> <pubkey3> <pubkey4> <pubkey5> OP_3 OP_CHECKMULTISIGVERIFY <pubkey3> OP_CHECKSIG

// Function Sign_BF_TX has the whole process of signing each BF_TX.
func Sign_BF_TX(bft_tx bf_tx.BF_TX) bf_tx.BF_TX {

    content := bf_tx.BF_TXContent(bft_tx)

    pubkeyCurve := elliptic.P256() //see http://golang.org/pkg/crypto/elliptic/#P256

    privatekey := new(ecdsa.PrivateKey)
    privatekey, err := ecdsa.GenerateKey(pubkeyCurve, rand.Reader) // this generates a public & private key pair

    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    pubkey := privatekey.PublicKey

    // Sign ecdsa style
    var h hash.Hash
    h = md5.New()
    r := big.NewInt(0)
    s := big.NewInt(0)

    io.WriteString(h, content)
    signhash := h.Sum(nil)

    r, s, serr := ecdsa.Sign(rand.Reader, privatekey, signhash)
    if serr != nil {
        fmt.Println(err)
        os.Exit(1)
    }

    signature := r.Bytes()
    signature = append(signature, s.Bytes()...)

    sign := ""
    for i, _ := range signature {
        sign += strconv.Itoa(int(signature[i]))
    }

    // Verification
    verifystatus := ecdsa.Verify(&pubkey, signhash, r, s)

    //Set Private Key and Sign to BF_TX
    bft_tx.PrivateKey = *privatekey
    bft_tx.Signhash = signhash
    bft_tx.Signature = sign
    bft_tx.Verified = verifystatus

    return bft_tx
}

// =================================================
// Blockfreight™ | The blockchain of global freight.
// =================================================

// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
// BBBBBBB                    BBBBBBBBBBBBBBBBBBB
// BBBBBBB                       BBBBBBBBBBBBBBBB
// BBBBBBB                        BBBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBB        BBBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBB        BBBBBBBBBBBBBBB
// BBBBBBB       BBBBBBB         BBBBBBBBBBBBBBBB
// BBBBBBB                     BBBBBBBBBBBBBBBBBB
// BBBBBBB                        BBBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBBB        BBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBBBB       BBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBBB        BBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBB        BBB       BBBBB
// BBBBBBB                       BBBB       BBBBB
// BBBBBBB                    BBBBBBB       BBBBB
// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB

// ==================================================
// Blockfreight™ | The blockchain for global freight.
// ==================================================
<|endoftext|>


<commit_before>package main

import (
	"context"
	"fmt"
	"math/rand"
	"runtime"
	"runtime/debug"
	"sort"
	"strconv"
	"sync"

	"fiber/src/templates"

	"github.com/gofiber/fiber"
	"github.com/gofiber/utils"
	pgx "github.com/jackc/pgx/v4"
	"github.com/jackc/pgx/v4/pgxpool"
)

var (
	child        bool
	db           *pgxpool.Pool
	cachedWorlds Worlds
)

const (
	queryparam       = "q"
	helloworld       = "Hello, World!"
	worldcount       = 10000
	worldselectsql   = "SELECT id, randomNumber FROM World WHERE id = $1"
	worldupdatesql   = "UPDATE World SET randomNumber = $1 WHERE id = $2"
	worldcachesql    = "SELECT * FROM World LIMIT $1"
	fortuneselectsql = "SELECT id, message FROM Fortune"
)

func main() {
	initDatabase()

	app := fiber.New(&fiber.Settings{
		CaseSensitive:            true,
		StrictRouting:            true,
		DisableHeaderNormalizing: true,
		ServerHeader:             "go",
	})

	if utils.GetArgument("-prefork-child") {
		child = true
	}
	if utils.GetArgument("-nogc") {
		debug.SetGCPercent(-1)
	}

	app.Get("/plaintext", plaintextHandler)
	app.Get("/json", jsonHandler)
	app.Get("/db", dbHandler)
	app.Get("/update", updateHandler)
	app.Get("/queries", queriesHandler)
	app.Get("/fortunes", templateHandler)
	app.Get("/cached-worlds", cachedHandler)
	app.Listen(8080)
}

// Message ...
type Message struct {
	Message string `json:"message"`
}

// Worlds ...
type Worlds []World

// World ...
type World struct {
	ID           int32 `json:"id"`
	RandomNumber int32 `json:"randomNumber"`
}

// JSONpool ...
var JSONpool = sync.Pool{
	New: func() interface{} {
		return new(Message)
	},
}

// AcquireJSON ...
func AcquireJSON() *Message {
	return JSONpool.Get().(*Message)
}

// ReleaseJSON ...
func ReleaseJSON(json *Message) {
	json.Message = ""
	JSONpool.Put(json)
}

// WorldPool ...
var WorldPool = sync.Pool{
	New: func() interface{} {
		return new(World)
	},
}

// AcquireWorld ...
func AcquireWorld() *World {
	return WorldPool.Get().(*World)
}

// ReleaseWorld ...
func ReleaseWorld(w *World) {
	w.ID = 0
	w.RandomNumber = 0
	WorldPool.Put(w)
}

// WorldsPool ...
var WorldsPool = sync.Pool{
	New: func() interface{} {
		return make(Worlds, 0, 500)
	},
}

// AcquireWorlds ...
func AcquireWorlds() Worlds {
	return WorldsPool.Get().(Worlds)
}

// ReleaseWorlds ...ReleaseWorlds
func ReleaseWorlds(w Worlds) {
	w = w[:0]
	WorldsPool.Put(w)
}

// initDatabase :
func initDatabase() {
	maxConn := runtime.NumCPU()
	if maxConn == 0 {
		maxConn = 8
	}
	if child {
		maxConn = maxConn
	} else {
		maxConn = maxConn * 4
	}

	var err error
	db, err = pgxpool.Connect(context.Background(), fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s pool_max_conns=%d", "tfb-database", 5432, "benchmarkdbuser", "benchmarkdbpass", "hello_world", maxConn))
	if err != nil {
		panic(err)
	}
	populateCache()
}

// this will populate the cached worlds for the cache test
func populateCache() {
	worlds := make(Worlds, worldcount)
	rows, err := db.Query(context.Background(), worldcachesql, worldcount)
	if err != nil {
		panic(err)
	}
	for i := 0; i < worldcount; i++ {
		w := &worlds[i]
		if !rows.Next() {
			break
		}
		if err := rows.Scan(&w.ID, &w.RandomNumber); err != nil {
			panic(err)
		}
		//db.QueryRow(context.Background(), worldselectsql, RandomWorld()).Scan(&w.ID, &w.RandomNumber)
	}
	cachedWorlds = worlds
}

// jsonHandler :
func jsonHandler(c *fiber.Ctx) {
	m := AcquireJSON()
	m.Message = helloworld
	c.JSON(&m)
	ReleaseJSON(m)
}

// dbHandler :
func dbHandler(c *fiber.Ctx) {
	w := AcquireWorld()
	db.QueryRow(context.Background(), worldselectsql, RandomWorld()).Scan(&w.ID, &w.RandomNumber)
	c.JSON(&w)
	ReleaseWorld(w)
}

// Frameworks/Go/fasthttp/src/server-postgresql/server.go#104
func templateHandler(c *fiber.Ctx) {
	rows, _ := db.Query(context.Background(), fortuneselectsql)

	var f templates.Fortune
	fortunes := make([]templates.Fortune, 0, 16)
	for rows.Next() {
		_ = rows.Scan(&f.ID, &f.Message)
		fortunes = append(fortunes, f)
	}
	rows.Close()
	fortunes = append(fortunes, templates.Fortune{
		Message: "Additional fortune added at request time.",
	})

	sort.Slice(fortunes, func(i, j int) bool {
		return fortunes[i].Message < fortunes[j].Message
	})

	c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)

	templates.WriteFortunePage(c.Fasthttp, fortunes)
}

// queriesHandler :
func queriesHandler(c *fiber.Ctx) {
	n := QueriesCount(c)
	worlds := AcquireWorlds()[:n]
	for i := 0; i < n; i++ {
		w := &worlds[i]
		db.QueryRow(context.Background(), worldselectsql, RandomWorld()).Scan(&w.ID, &w.RandomNumber)
	}
	c.JSON(&worlds)
	ReleaseWorlds(worlds)
}

// updateHandler :
func updateHandler(c *fiber.Ctx) {
	n := QueriesCount(c)
	worlds := AcquireWorlds()[:n]
	for i := 0; i < n; i++ {
		w := &worlds[i]
		db.QueryRow(context.Background(), worldselectsql, RandomWorld()).Scan(&w.ID, &w.RandomNumber)
		w.RandomNumber = int32(RandomWorld())
	}
	// sorting is required for insert deadlock prevention.
	sort.Slice(worlds, func(i, j int) bool {
		return worlds[i].ID < worlds[j].ID
	})

	batch := pgx.Batch{}
	for _, w := range worlds {
		batch.Queue(worldupdatesql, w.RandomNumber, w.ID)
	}
	db.SendBatch(context.Background(), &batch).Close()
	c.JSON(&worlds)
	ReleaseWorlds(worlds)
}

var helloworldRaw = []byte("Hello, World!")

// plaintextHandler :
func plaintextHandler(c *fiber.Ctx) {
	c.SendBytes(helloworldRaw)
}

// cachedHandler :
func cachedHandler(c *fiber.Ctx) {
	n := QueriesCount(c)
	worlds := AcquireWorlds()[:n]
	for i := 0; i < n; i++ {
		worlds[i] = cachedWorlds[RandomWorld()-1]
	}
	c.JSON(&worlds)
	ReleaseWorlds(worlds)
}

// RandomWorld :
func RandomWorld() int {
	return rand.Intn(worldcount) + 1
}

// QueriesCount :
func QueriesCount(c *fiber.Ctx) int {
	n, _ := strconv.Atoi(c.Query(queryparam))
	if n < 1 {
		n = 1
	} else if n > 500 {
		n = 500
	}
	return n
}
<commit_msg>🐛 Fiber: Fix Prefork (#5878)<commit_after>package main

import (
	"context"
	"fmt"
	"math/rand"
	"runtime"
	"runtime/debug"
	"sort"
	"strconv"
	"sync"

	"fiber/src/templates"

	"github.com/gofiber/fiber"
	"github.com/gofiber/utils"
	pgx "github.com/jackc/pgx/v4"
	"github.com/jackc/pgx/v4/pgxpool"
)

var (
	child        bool
	db           *pgxpool.Pool
	cachedWorlds Worlds
)

const (
	queryparam       = "q"
	helloworld       = "Hello, World!"
	worldcount       = 10000
	worldselectsql   = "SELECT id, randomNumber FROM World WHERE id = $1"
	worldupdatesql   = "UPDATE World SET randomNumber = $1 WHERE id = $2"
	worldcachesql    = "SELECT * FROM World LIMIT $1"
	fortuneselectsql = "SELECT id, message FROM Fortune"
)

func main() {
	initDatabase()

	app := fiber.New(&fiber.Settings{
		CaseSensitive:            true,
		StrictRouting:            true,
		DisableHeaderNormalizing: true,
		ServerHeader:             "go",
	})
	if utils.GetArgument("-prefork") {
		app.Settings.Prefork = true
	}
	if utils.GetArgument("-prefork-child") {
		child = true
	}
	if utils.GetArgument("-nogc") {
		debug.SetGCPercent(-1)
	}

	if utils.GetArgument("-prefork-child") {
		child = true
	}
	if utils.GetArgument("-nogc") {
		debug.SetGCPercent(-1)
	}

	app.Get("/plaintext", plaintextHandler)
	app.Get("/json", jsonHandler)
	app.Get("/db", dbHandler)
	app.Get("/update", updateHandler)
	app.Get("/queries", queriesHandler)
	app.Get("/fortunes", templateHandler)
	app.Get("/cached-worlds", cachedHandler)
	app.Listen(8080)
}

// Message ...
type Message struct {
	Message string `json:"message"`
}

// Worlds ...
type Worlds []World

// World ...
type World struct {
	ID           int32 `json:"id"`
	RandomNumber int32 `json:"randomNumber"`
}

// JSONpool ...
var JSONpool = sync.Pool{
	New: func() interface{} {
		return new(Message)
	},
}

// AcquireJSON ...
func AcquireJSON() *Message {
	return JSONpool.Get().(*Message)
}

// ReleaseJSON ...
func ReleaseJSON(json *Message) {
	json.Message = ""
	JSONpool.Put(json)
}

// WorldPool ...
var WorldPool = sync.Pool{
	New: func() interface{} {
		return new(World)
	},
}

// AcquireWorld ...
func AcquireWorld() *World {
	return WorldPool.Get().(*World)
}

// ReleaseWorld ...
func ReleaseWorld(w *World) {
	w.ID = 0
	w.RandomNumber = 0
	WorldPool.Put(w)
}

// WorldsPool ...
var WorldsPool = sync.Pool{
	New: func() interface{} {
		return make(Worlds, 0, 500)
	},
}

// AcquireWorlds ...
func AcquireWorlds() Worlds {
	return WorldsPool.Get().(Worlds)
}

// ReleaseWorlds ...ReleaseWorlds
func ReleaseWorlds(w Worlds) {
	w = w[:0]
	WorldsPool.Put(w)
}

// initDatabase :
func initDatabase() {
	maxConn := runtime.NumCPU()
	if maxConn == 0 {
		maxConn = 8
	}
	if child {
		maxConn = maxConn
	} else {
		maxConn = maxConn * 4
	}

	var err error
	db, err = pgxpool.Connect(context.Background(), fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s pool_max_conns=%d", "tfb-database", 5432, "benchmarkdbuser", "benchmarkdbpass", "hello_world", maxConn))
	if err != nil {
		panic(err)
	}
	populateCache()
}

// this will populate the cached worlds for the cache test
func populateCache() {
	worlds := make(Worlds, worldcount)
	rows, err := db.Query(context.Background(), worldcachesql, worldcount)
	if err != nil {
		panic(err)
	}
	for i := 0; i < worldcount; i++ {
		w := &worlds[i]
		if !rows.Next() {
			break
		}
		if err := rows.Scan(&w.ID, &w.RandomNumber); err != nil {
			panic(err)
		}
		//db.QueryRow(context.Background(), worldselectsql, RandomWorld()).Scan(&w.ID, &w.RandomNumber)
	}
	cachedWorlds = worlds
}

// jsonHandler :
func jsonHandler(c *fiber.Ctx) {
	m := AcquireJSON()
	m.Message = helloworld
	c.JSON(&m)
	ReleaseJSON(m)
}

// dbHandler :
func dbHandler(c *fiber.Ctx) {
	w := AcquireWorld()
	db.QueryRow(context.Background(), worldselectsql, RandomWorld()).Scan(&w.ID, &w.RandomNumber)
	c.JSON(&w)
	ReleaseWorld(w)
}

// Frameworks/Go/fasthttp/src/server-postgresql/server.go#104
func templateHandler(c *fiber.Ctx) {
	rows, _ := db.Query(context.Background(), fortuneselectsql)

	var f templates.Fortune
	fortunes := make([]templates.Fortune, 0, 16)
	for rows.Next() {
		_ = rows.Scan(&f.ID, &f.Message)
		fortunes = append(fortunes, f)
	}
	rows.Close()
	fortunes = append(fortunes, templates.Fortune{
		Message: "Additional fortune added at request time.",
	})

	sort.Slice(fortunes, func(i, j int) bool {
		return fortunes[i].Message < fortunes[j].Message
	})

	c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)

	templates.WriteFortunePage(c.Fasthttp, fortunes)
}

// queriesHandler :
func queriesHandler(c *fiber.Ctx) {
	n := QueriesCount(c)
	worlds := AcquireWorlds()[:n]
	for i := 0; i < n; i++ {
		w := &worlds[i]
		db.QueryRow(context.Background(), worldselectsql, RandomWorld()).Scan(&w.ID, &w.RandomNumber)
	}
	c.JSON(&worlds)
	ReleaseWorlds(worlds)
}

// updateHandler :
func updateHandler(c *fiber.Ctx) {
	n := QueriesCount(c)
	worlds := AcquireWorlds()[:n]
	for i := 0; i < n; i++ {
		w := &worlds[i]
		db.QueryRow(context.Background(), worldselectsql, RandomWorld()).Scan(&w.ID, &w.RandomNumber)
		w.RandomNumber = int32(RandomWorld())
	}
	// sorting is required for insert deadlock prevention.
	sort.Slice(worlds, func(i, j int) bool {
		return worlds[i].ID < worlds[j].ID
	})

	batch := pgx.Batch{}
	for _, w := range worlds {
		batch.Queue(worldupdatesql, w.RandomNumber, w.ID)
	}
	db.SendBatch(context.Background(), &batch).Close()
	c.JSON(&worlds)
	ReleaseWorlds(worlds)
}

var helloworldRaw = []byte("Hello, World!")

// plaintextHandler :
func plaintextHandler(c *fiber.Ctx) {
	c.SendBytes(helloworldRaw)
}

// cachedHandler :
func cachedHandler(c *fiber.Ctx) {
	n := QueriesCount(c)
	worlds := AcquireWorlds()[:n]
	for i := 0; i < n; i++ {
		worlds[i] = cachedWorlds[RandomWorld()-1]
	}
	c.JSON(&worlds)
	ReleaseWorlds(worlds)
}

// RandomWorld :
func RandomWorld() int {
	return rand.Intn(worldcount) + 1
}

// QueriesCount :
func QueriesCount(c *fiber.Ctx) int {
	n, _ := strconv.Atoi(c.Query(queryparam))
	if n < 1 {
		n = 1
	} else if n > 500 {
		n = 500
	}
	return n
}
<|endoftext|>


<commit_before>package gateway

import (
	"net/url"

	"log"

	"github.com/ReneGa/tweetcount-microservices/ingestor/client"
	"github.com/ReneGa/tweetcount-microservices/ingestor/domain"
	"github.com/chimeracoder/anaconda"
)

// Twitter is a gateway to the Twitter streaming API
type Twitter interface {
	Tweets(query string) domain.Tweets
}

// NewAnacondaTwitter creates a new Twitter client
func NewAnacondaTwitter(
	anaconda client.Anaconda,
	key string,
	keySecret string,
	token string,
	tokenSecret string,
) Twitter {
	anaconda.SetConsumerKey(key)
	anaconda.SetConsumerSecret(keySecret)
	api := anaconda.NewTwitterAPI(token, tokenSecret)
	return &anacondaTwitter{api}
}

type anacondaTwitter struct{ client.AnacondaAPI }

// Tweets returns a stream of public Tweets for a given search query.
func (a anacondaTwitter) Tweets(query string) domain.Tweets {
	stream := a.PublicStreamFilter(url.Values{
		"track": {query},
	})
	anacondaChan := stream.C()
	out := make(chan domain.Tweet)
	stop := make(chan bool)

	tweets := domain.Tweets{
		Data: out,
		Stop: stop,
	}

	go func() {
		defer close(out)
		defer stream.Stop()
		for {
			select {
			case item := <-anacondaChan:
				log.Println(item)
				if t, ok := item.(anaconda.Tweet); ok {
					tweetTime, _ := t.CreatedAtTime()
					out <- domain.Tweet{
						Text: t.Text,
						ID:   t.IdStr,
						Time: tweetTime,
					}
				}
			case <-stop:
				return
			}
		}
	}()

	return tweets
}
<commit_msg>remove debug log<commit_after>package gateway

import (
	"net/url"

	"github.com/ReneGa/tweetcount-microservices/ingestor/client"
	"github.com/ReneGa/tweetcount-microservices/ingestor/domain"
	"github.com/chimeracoder/anaconda"
)

// Twitter is a gateway to the Twitter streaming API
type Twitter interface {
	Tweets(query string) domain.Tweets
}

// NewAnacondaTwitter creates a new Twitter client
func NewAnacondaTwitter(
	anaconda client.Anaconda,
	key string,
	keySecret string,
	token string,
	tokenSecret string,
) Twitter {
	anaconda.SetConsumerKey(key)
	anaconda.SetConsumerSecret(keySecret)
	api := anaconda.NewTwitterAPI(token, tokenSecret)
	return &anacondaTwitter{api}
}

type anacondaTwitter struct{ client.AnacondaAPI }

// Tweets returns a stream of public Tweets for a given search query.
func (a anacondaTwitter) Tweets(query string) domain.Tweets {
	stream := a.PublicStreamFilter(url.Values{
		"track": {query},
	})
	anacondaChan := stream.C()
	out := make(chan domain.Tweet)
	stop := make(chan bool)

	tweets := domain.Tweets{
		Data: out,
		Stop: stop,
	}

	go func() {
		defer close(out)
		defer stream.Stop()
		for {
			select {
			case item := <-anacondaChan:
				if t, ok := item.(anaconda.Tweet); ok {
					tweetTime, _ := t.CreatedAtTime()
					out <- domain.Tweet{
						Text: t.Text,
						ID:   t.IdStr,
						Time: tweetTime,
					}
				}
			case <-stop:
				return
			}
		}
	}()

	return tweets
}
<|endoftext|>


<commit_before>package user

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"time"

	"github.com/sethgrid/pester"
	"github.com/starptech/go-web/feed"
)

// Example only configurable with env variables
//
// store := feed.NewMemoryStore()
// uf := userFeed.NewUser(feed.Config{Table: "user", Interval: 5, URL: "http://example.de/feed"}, store)
// go uf.Start()
//
// The feed endpoint accept a parameter called "last" which is used as cursor for the current feed position
// This cursor will be saved when the update process is done
// GET http://example.de/feed?last=1503769504008
// { "items": [{ "name": "peter" }] }
//

type Feed struct {
	after  uint64
	ticker *time.Ticker
	store  feed.FeedStore
	config feed.Config
}

// NewUser start the timer and return a new userFeed instance
func NewUser(config feed.Config, s feed.FeedStore) *Feed {
	u := &Feed{}
	u.config = config
	u.store = s
	u.after = u.store.GetPosition(u.config.Table)
	u.ticker = time.NewTicker(time.Duration(u.config.Interval) * time.Second)
	return u
}

// Start poll updates in certain intervals
func (u *Feed) Start() {
	for range u.ticker.C {
		u.poll(u.after)
	}
}

// poll start a request against the feed endpoint
func (u *Feed) poll(last uint64) {
	feed, err := u.request()

	if err != nil {
		switch err.(type) {
		default:
			fmt.Println(err)
		}
	} else if err := u.store.Save(feed); err == nil {
		u.store.SetPosition(u.config.Table, last)
	}

	fmt.Println(feed)
}

// Request the feed endpoint and return the feed results
func (u *Feed) request() (*feed.RootFeed, error) {
	client := pester.New()
	client.Concurrency = 3
	client.MaxRetries = 5
	client.Backoff = pester.ExponentialBackoff
	client.KeepLog = true

	resp, err := client.Get(u.config.URL + "?after=" + string(u.after))
	defer func() {
		err := resp.Body.Close()
		if err != nil {
			log.Printf("error closing response body %q\n", err)
		}
	}()

	if err != nil {
		return nil, feed.ErrClient
	}

	payload, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		return nil, feed.ErrReadBody
	}

	f := &feed.RootFeed{}
	if err := json.Unmarshal(payload, f); err != nil {
		return nil, feed.ErrUnMarshaling
	}

	return f, nil
}
<commit_msg>Update user.go<commit_after>package user

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"time"

	"github.com/sethgrid/pester"
	"github.com/starptech/go-web/feed"
)

// Example:
// cfg := feed.Config{Table: "user", Interval: 5, URL: "http://example.de/feed"}
// store := feed.NewMemoryStore()
// uf := userFeed.NewUser(cfg, store)
// go uf.Start()
//
// The feed endpoint accept a parameter called "last" which is used as cursor for the current feed position
// This cursor will be saved when the update process is done
// GET http://example.de/feed?last=1503769504008
// { "items": [{ "name": "peter" }] }
//

type Feed struct {
	after  uint64
	ticker *time.Ticker
	store  feed.FeedStore
	config feed.Config
}

// NewUser start the timer and return a new userFeed instance
func NewUser(config feed.Config, s feed.FeedStore) *Feed {
	u := &Feed{}
	u.config = config
	u.store = s
	u.after = u.store.GetPosition(u.config.Table)
	u.ticker = time.NewTicker(time.Duration(u.config.Interval) * time.Second)
	return u
}

// Start poll updates in certain intervals
func (u *Feed) Start() {
	for range u.ticker.C {
		u.poll(u.after)
	}
}

// poll start a request against the feed endpoint
func (u *Feed) poll(last uint64) {
	feed, err := u.request()

	if err != nil {
		switch err.(type) {
		default:
			fmt.Println(err)
		}
	} else if err := u.store.Save(feed); err == nil {
		u.store.SetPosition(u.config.Table, last)
	}

	fmt.Println(feed)
}

// Request the feed endpoint and return the feed results
func (u *Feed) request() (*feed.RootFeed, error) {
	client := pester.New()
	client.Concurrency = 3
	client.MaxRetries = 5
	client.Backoff = pester.ExponentialBackoff
	client.KeepLog = true

	resp, err := client.Get(u.config.URL + "?after=" + string(u.after))
	defer func() {
		err := resp.Body.Close()
		if err != nil {
			log.Printf("error closing response body %q\n", err)
		}
	}()

	if err != nil {
		return nil, feed.ErrClient
	}

	payload, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		return nil, feed.ErrReadBody
	}

	f := &feed.RootFeed{}
	if err := json.Unmarshal(payload, f); err != nil {
		return nil, feed.ErrUnMarshaling
	}

	return f, nil
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"github.com/russross/blackfriday"
	"io/ioutil"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
	"time"
)

type FileRepository struct {
	directory string
	posts BlogPosts
	tags []string
}

func NewFileRepository(directory string) *FileRepository {

	f := new(FileRepository)
	f.directory = directory
	f.posts, _ = f.fetchAllPosts()
	f.tags = f.fetchAllTags()

	return f
}

func (f *FileRepository) AllTags() []string {
	return f.tags
}

func (f *FileRepository) AllPosts() BlogPosts {
	return f.posts
}

func (f *FileRepository) PostWithUrl(url string) (*BlogPost, error) {

	for i := range f.posts {
		if f.posts[i].Url() == url {
			return f.posts[i], nil
		}
	}

	err := errors.New("Could not find post")

	return nil, err
}

func (f *FileRepository) PostsWithTag(tag string) BlogPosts {

	filteredPosts := BlogPosts{}

	for i := range f.posts {
		if f.posts[i].ContainsTag(tag) {
			filteredPosts = append(filteredPosts, f.posts[i])
		}
	}

	return filteredPosts
}

func (f *FileRepository) PostsInRange(start, count int) BlogPosts {

	if start + count > len(f.posts) {
		count = len(f.posts) - start
	}

	return f.posts[start:start + count]
}

func (f *FileRepository) fetchAllPosts() (BlogPosts, error) {

	dirname := f.directory + string(filepath.Separator)

	files, err := ioutil.ReadDir(dirname)

	posts := BlogPosts{}

	for i := range files {

		if files[i].IsDir() {
			continue
		}

		if filepath.Ext(files[i].Name()) != ".md" {
			continue
		}

		post, err := f.fetchPost(files[i].Name())

		if err != nil {
			return nil, err
		}

		posts = append(posts, post)
	}

	sort.Sort(posts)

	return posts, err
}

func (f *FileRepository) fetchAllTags() []string {

	// We're using a map to simulate a set
	tagMap := make(map[string]bool)

	for i := range f.posts {
		for j := range f.posts[i].Tags() {
			tagMap[strings.ToLower(f.posts[i].Tags()[j])] = true
		}
	}

	tags := []string{}

	for key := range tagMap {
		tags = append(tags, key)
	}

	sort.Strings(tags)

	return tags
}

func (f *FileRepository) fetchPost(filename string) (*BlogPost, error) {

	post := new(BlogPost)

	dirname := f.directory + string(filepath.Separator)

	file, err := ioutil.ReadFile(dirname + filename)

	if err != nil {
		return post, err
	}

	file = []byte(f.extractHeader(string(file), post))

	htmlFlags := blackfriday.HTML_USE_SMARTYPANTS
	extensions := blackfriday.EXTENSION_HARD_LINE_BREAK | blackfriday.EXTENSION_FENCED_CODE | blackfriday.EXTENSION_NO_INTRA_EMPHASIS

	renderer := blackfriday.HtmlRenderer(htmlFlags, post.Title(), "")

	output := blackfriday.Markdown(file, renderer, extensions)

	post.SetBody(string(output))

	return post, nil
}

func (f *FileRepository) extractHeader(text string, post *BlogPost) string {

	lines := strings.Split(text, "\n")

	headerSize := 0

	for i := range lines {
		if strings.Contains(lines[i], ":") {
			components := strings.Split(lines[i], ":")

			header := strings.ToLower(strings.Trim(components[0], " "))
			separatorIndex := strings.Index(lines[i], ":") + 1
			data := strings.Trim(lines[i][separatorIndex:], " ")

			switch header {
			case "title":
				post.SetTitle(data)
			case "tags":

				tags := strings.Split(data, ",")

				formattedTags := []string{}

				for j := range tags {
					tags[j] = strings.Trim(tags[j], " ")
					tags[j] = strings.Replace(tags[j], " ", "-", -1)

					if tags[j] != "" {
						formattedTags = append(formattedTags, tags[j])
					}
				}

				post.SetTags(formattedTags)
			case "date":
				post.SetPublishDate(stringToTime(data))
			default:
				continue
			}

			headerSize += len(lines[i]) + 1
		} else {
			break
		}
	}

	return text[headerSize:]
}

func stringToTime(s string) time.Time {

	year, err := strconv.Atoi(s[:4])

	if err != nil {
		return time.Unix(0, 0)
	}

	month, err := strconv.Atoi(s[5:7])

	if err != nil {
		return time.Unix(0, 0)
	}

	day, err := strconv.Atoi(s[8:10])

	if err != nil {
		return time.Unix(0, 0)
	}

	hour, err := strconv.Atoi(s[11:13])

	if err != nil {
		return time.Unix(0, 0)
	}

	minute, err := strconv.Atoi(s[14:16])

	if err != nil {
		return time.Unix(0, 0)
	}

	seconds, err := strconv.Atoi(s[17:19])

	if err != nil {
		return time.Unix(0, 0)
	}

	location, err := time.LoadLocation("UTC")

	return time.Date(year, time.Month(month), day, hour, minute, seconds, 0, location)
}
<commit_msg>Added mutexes to file repository functions. File repository updates its cache every 10 minutes.<commit_after>package main

import (
	"errors"
	"github.com/russross/blackfriday"
	"io/ioutil"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
	"time"
	"sync"
)

type FileRepository struct {
	directory string
	posts BlogPosts
	tags []string
	lastUpdated time.Time
	mutex sync.RWMutex
}

func NewFileRepository(directory string) *FileRepository {

	f := new(FileRepository)
	f.directory = directory

	f.fetchAllPosts()
	f.fetchAllTags()

	f.lastUpdated = time.Now()

	go f.update()

	return f
}

func (f *FileRepository) AllTags() []string {
	return f.tags
}

func (f *FileRepository) AllPosts() BlogPosts {
	return f.posts
}

func (f *FileRepository) PostWithUrl(url string) (*BlogPost, error) {

	f.mutex.RLock()
	defer f.mutex.RUnlock()

	for i := range f.posts {
		if f.posts[i].Url() == url {
			return f.posts[i], nil
		}
	}

	err := errors.New("Could not find post")

	return nil, err
}

func (f *FileRepository) PostsWithTag(tag string) BlogPosts {

	f.mutex.RLock()
	defer f.mutex.RUnlock()

	filteredPosts := BlogPosts{}

	for i := range f.posts {
		if f.posts[i].ContainsTag(tag) {
			filteredPosts = append(filteredPosts, f.posts[i])
		}
	}

	return filteredPosts
}

func (f *FileRepository) PostsInRange(start, count int) BlogPosts {

	f.mutex.RLock()
	defer f.mutex.RUnlock()

	if start + count > len(f.posts) {
		count = len(f.posts) - start
	}

	return f.posts[start:start + count]
}

func (f *FileRepository) update() {

	f.mutex.Lock()
	defer f.mutex.Unlock()

	for {
		f.fetchAllPosts()
		f.fetchAllTags()
		f.lastUpdated = time.Now()

		time.Sleep(10 * time.Minute)
	}
}

func (f *FileRepository) fetchAllPosts() error {

	f.mutex.Lock()
	defer f.mutex.Unlock()

	dirname := f.directory + string(filepath.Separator)

	files, err := ioutil.ReadDir(dirname)

	f.posts = BlogPosts{}

	for i := range files {

		if files[i].IsDir() {
			continue
		}

		if filepath.Ext(files[i].Name()) != ".md" {
			continue
		}

		post, err := f.fetchPost(files[i].Name())

		if err != nil {
			return err
		}

		f.posts = append(f.posts, post)
	}

	sort.Sort(f.posts)

	return err
}

func (f *FileRepository) fetchAllTags() {

	f.mutex.Lock()
	defer f.mutex.Unlock()

	// We're using a map to simulate a set
	tagMap := make(map[string]bool)

	for i := range f.posts {
		for j := range f.posts[i].Tags() {
			tagMap[strings.ToLower(f.posts[i].Tags()[j])] = true
		}
	}

	f.tags = []string{}

	for key := range tagMap {
		f.tags = append(f.tags, key)
	}

	sort.Strings(f.tags)
}

func (f *FileRepository) fetchPost(filename string) (*BlogPost, error) {

	post := new(BlogPost)

	dirname := f.directory + string(filepath.Separator)

	file, err := ioutil.ReadFile(dirname + filename)

	if err != nil {
		return post, err
	}

	file = []byte(f.extractHeader(string(file), post))

	htmlFlags := blackfriday.HTML_USE_SMARTYPANTS
	extensions := blackfriday.EXTENSION_HARD_LINE_BREAK | blackfriday.EXTENSION_FENCED_CODE | blackfriday.EXTENSION_NO_INTRA_EMPHASIS

	renderer := blackfriday.HtmlRenderer(htmlFlags, post.Title(), "")

	output := blackfriday.Markdown(file, renderer, extensions)

	post.SetBody(string(output))

	return post, nil
}

func (f *FileRepository) extractHeader(text string, post *BlogPost) string {

	lines := strings.Split(text, "\n")

	headerSize := 0

	for i := range lines {
		if strings.Contains(lines[i], ":") {
			components := strings.Split(lines[i], ":")

			header := strings.ToLower(strings.Trim(components[0], " "))
			separatorIndex := strings.Index(lines[i], ":") + 1
			data := strings.Trim(lines[i][separatorIndex:], " ")

			switch header {
			case "title":
				post.SetTitle(data)
			case "tags":

				tags := strings.Split(data, ",")

				formattedTags := []string{}

				for j := range tags {
					tags[j] = strings.Trim(tags[j], " ")
					tags[j] = strings.Replace(tags[j], " ", "-", -1)

					if tags[j] != "" {
						formattedTags = append(formattedTags, tags[j])
					}
				}

				post.SetTags(formattedTags)
			case "date":
				post.SetPublishDate(stringToTime(data))
			default:
				continue
			}

			headerSize += len(lines[i]) + 1
		} else {
			break
		}
	}

	return text[headerSize:]
}

func stringToTime(s string) time.Time {

	year, err := strconv.Atoi(s[:4])

	if err != nil {
		return time.Unix(0, 0)
	}

	month, err := strconv.Atoi(s[5:7])

	if err != nil {
		return time.Unix(0, 0)
	}

	day, err := strconv.Atoi(s[8:10])

	if err != nil {
		return time.Unix(0, 0)
	}

	hour, err := strconv.Atoi(s[11:13])

	if err != nil {
		return time.Unix(0, 0)
	}

	minute, err := strconv.Atoi(s[14:16])

	if err != nil {
		return time.Unix(0, 0)
	}

	seconds, err := strconv.Atoi(s[17:19])

	if err != nil {
		return time.Unix(0, 0)
	}

	location, err := time.LoadLocation("UTC")

	return time.Date(year, time.Month(month), day, hour, minute, seconds, 0, location)
}
<|endoftext|>


<commit_before>// Copyright 2016 The Gosl Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package al

import (
	"testing"

	"github.com/cpmech/gosl/chk"
	"github.com/cpmech/gosl/io"
)

func TestQueue01(tst *testing.T) {

	//verbose()
	chk.PrintTitle("Queue01")

	guessedMaxSize := 20
	qu := NewQueue(guessedMaxSize)
	member := qu.Out()
	if member != nil {
		tst.Errorf("returned member should be nil in an empty Queue\n")
		return
	}
	qu.Debug = true

	// add
	io.PfYel("In(l)\n")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 0)
	qu.In(FromString("l"))
	chk.String(tst, "[l]", io.Sf("%v", qu.ring))
	chk.String(tst, "[l]", qu.String())
	chk.String(tst, ToString(qu.Front()), "l")
	chk.String(tst, ToString(qu.Back()), "l")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 1)

	io.PfYel("\nIn(o)\n")
	qu.In(FromString("o"))
	chk.String(tst, "[l o]", io.Sf("%v", qu.ring))
	chk.String(tst, "[l o]", qu.String())
	chk.String(tst, ToString(qu.Front()), "l")
	chk.String(tst, ToString(qu.Back()), "o")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 2)

	io.PfYel("\nIn(v)\n")
	qu.In(FromString("v"))
	chk.String(tst, "[l o v]", io.Sf("%v", qu.ring))
	chk.String(tst, "[l o v]", qu.String())
	chk.String(tst, ToString(qu.Front()), "l")
	chk.String(tst, ToString(qu.Back()), "v")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 3)

	// remove
	io.PfYel("\nOut(l)\n")
	res := ToString(qu.Out())
	chk.String(tst, "[l o v]", io.Sf("%v", qu.ring))
	chk.String(tst, "[o v]", qu.String())
	chk.String(tst, res, "l")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 2)

	io.PfYel("\nOut(o)\n")
	res = ToString(qu.Out())
	chk.String(tst, "[l o v]", io.Sf("%v", qu.ring))
	chk.String(tst, "[v]", qu.String())
	chk.String(tst, res, "o")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 1)

	io.PfYel("\nOut(v)\n")
	res = ToString(qu.Out())
	chk.String(tst, "[l o v]", io.Sf("%v", qu.ring))
	chk.String(tst, "[]", qu.String())
	chk.String(tst, res, "v")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 0)

	// try to remove more in empty queue
	io.PfYel("\nOut(nothing)\n")
	member = qu.Out()
	if member != nil {
		tst.Errorf("returned member should be nil in an empty Queue\n")
		return
	}
	chk.String(tst, "[]", qu.String())
	chk.Int(tst, "len(queue)", qu.Nmembers(), 0)

	// add again
	io.PfYel("\nIn(a)\n")
	qu.In(FromString("a"))
	chk.String(tst, "[a o v]", io.Sf("%v", qu.ring))
	chk.String(tst, "[a]", qu.String())
	chk.String(tst, ToString(qu.Front()), "a")
	chk.String(tst, ToString(qu.Back()), "a")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 1)

	io.PfYel("\nIn(b)\n")
	qu.In(FromString("b"))
	chk.String(tst, "[a b v]", io.Sf("%v", qu.ring))
	chk.String(tst, "[a b]", qu.String())
	chk.String(tst, ToString(qu.Front()), "a")
	chk.String(tst, ToString(qu.Back()), "b")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 2)

	io.PfYel("\nOut(a)\n")
	res = ToString(qu.Out())
	chk.String(tst, "[a b v]", io.Sf("%v", qu.ring))
	chk.String(tst, "[b]", qu.String())
	chk.String(tst, ToString(qu.Front()), "b")
	chk.String(tst, ToString(qu.Back()), "b")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 1)

	io.PfYel("\nIn(a) again\n")
	qu.In(FromString("a"))
	chk.String(tst, "[a b a]", io.Sf("%v", qu.ring))
	chk.String(tst, "[b a]", qu.String())
	chk.String(tst, ToString(qu.Front()), "b")
	chk.String(tst, ToString(qu.Back()), "a")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 2)

	io.PfYel("\nIn(c)\n")
	qu.In(FromString("c"))
	chk.String(tst, "[c b a]", io.Sf("%v", qu.ring))
	chk.String(tst, "[b a c]", qu.String())
	chk.String(tst, ToString(qu.Front()), "b")
	chk.String(tst, ToString(qu.Back()), "c")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 3)

	io.PfYel("\nIn(x)\n")
	qu.In(FromString("x"))
	chk.String(tst, "[b a c x]", io.Sf("%v", qu.ring))
	chk.String(tst, "[b a c x]", qu.String())
	chk.String(tst, ToString(qu.Front()), "b")
	chk.String(tst, ToString(qu.Back()), "x")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 4)

	io.PfYel("\nOut(b)\n")
	res = ToString(qu.Out())
	chk.String(tst, "[b a c x]", io.Sf("%v", qu.ring))
	chk.String(tst, "[a c x]", qu.String())
	chk.String(tst, ToString(qu.Front()), "a")
	chk.String(tst, ToString(qu.Back()), "x")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 3)

	io.PfYel("\nOut(a)\n")
	res = ToString(qu.Out())
	chk.String(tst, "[b a c x]", io.Sf("%v", qu.ring))
	chk.String(tst, "[c x]", qu.String())
	chk.String(tst, ToString(qu.Front()), "c")
	chk.String(tst, ToString(qu.Back()), "x")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 2)

	io.PfYel("\nOut(c)\n")
	res = ToString(qu.Out())
	chk.String(tst, "[b a c x]", io.Sf("%v", qu.ring))
	chk.String(tst, "[x]", qu.String())
	chk.String(tst, ToString(qu.Front()), "x")
	chk.String(tst, ToString(qu.Back()), "x")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 1)

	io.PfYel("\nOut(x)\n")
	res = ToString(qu.Out())
	chk.String(tst, "[b a c x]", io.Sf("%v", qu.ring))
	chk.String(tst, "[]", qu.String())
	chk.Int(tst, "len(queue)", qu.Nmembers(), 0)

	io.PfYel("\nOut(nothing)\n")
	chk.String(tst, "[b a c x]", io.Sf("%v", qu.ring))
	chk.String(tst, "[]", qu.String())
	chk.Int(tst, "len(queue)", qu.Nmembers(), 0)

	io.PfYel("\nIn(i)\n")
	qu.In(FromString("i"))
	chk.String(tst, "[i a c x]", io.Sf("%v", qu.ring))
	chk.String(tst, "[i]", qu.String())
	chk.String(tst, ToString(qu.Front()), "i")
	chk.String(tst, ToString(qu.Back()), "i")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 1)

	io.PfYel("\nIn(j)\n")
	qu.In(FromString("j"))
	chk.String(tst, "[i j c x]", io.Sf("%v", qu.ring))
	chk.String(tst, "[i j]", qu.String())
	chk.String(tst, ToString(qu.Front()), "i")
	chk.String(tst, ToString(qu.Back()), "j")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 2)
}
<commit_msg>Improve test<commit_after>// Copyright 2016 The Gosl Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package al

import (
	"testing"

	"github.com/cpmech/gosl/chk"
	"github.com/cpmech/gosl/io"
)

func TestQueue01(tst *testing.T) {

	//verbose()
	chk.PrintTitle("Queue01")

	guessedMaxSize := 20
	qu := NewQueue(guessedMaxSize)
	member := qu.Out()
	if member != nil {
		tst.Errorf("returned member should be nil in an empty Queue\n")
		return
	}
	qu.Debug = true

	// add
	io.PfYel("In(l)\n")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 0)
	qu.In(FromString("l"))
	chk.String(tst, "[l]", io.Sf("%v", qu.ring))
	chk.String(tst, "[l]", qu.String())
	chk.String(tst, ToString(qu.Front()), "l")
	chk.String(tst, ToString(qu.Back()), "l")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 1)

	io.PfYel("\nIn(o)\n")
	qu.In(FromString("o"))
	chk.String(tst, "[l o]", io.Sf("%v", qu.ring))
	chk.String(tst, "[l o]", qu.String())
	chk.String(tst, ToString(qu.Front()), "l")
	chk.String(tst, ToString(qu.Back()), "o")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 2)

	io.PfYel("\nIn(v)\n")
	qu.In(FromString("v"))
	chk.String(tst, "[l o v]", io.Sf("%v", qu.ring))
	chk.String(tst, "[l o v]", qu.String())
	chk.String(tst, ToString(qu.Front()), "l")
	chk.String(tst, ToString(qu.Back()), "v")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 3)

	// remove
	io.PfYel("\nOut(l)\n")
	res := ToString(qu.Out())
	chk.String(tst, "[l o v]", io.Sf("%v", qu.ring))
	chk.String(tst, "[o v]", qu.String())
	chk.String(tst, res, "l")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 2)

	io.PfYel("\nOut(o)\n")
	res = ToString(qu.Out())
	chk.String(tst, "[l o v]", io.Sf("%v", qu.ring))
	chk.String(tst, "[v]", qu.String())
	chk.String(tst, res, "o")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 1)

	io.PfYel("\nOut(v)\n")
	res = ToString(qu.Out())
	chk.String(tst, "[l o v]", io.Sf("%v", qu.ring))
	chk.String(tst, "[]", qu.String())
	chk.String(tst, res, "v")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 0)

	// try to remove more in empty queue
	io.PfYel("\nOut(nothing)\n")
	member = qu.Out()
	if member != nil {
		tst.Errorf("returned member should be nil in an empty Queue\n")
		return
	}
	chk.String(tst, "[]", qu.String())
	chk.Int(tst, "len(queue)", qu.Nmembers(), 0)

	// add again
	io.PfYel("\nIn(a)\n")
	qu.In(FromString("a"))
	chk.String(tst, "[a o v]", io.Sf("%v", qu.ring))
	chk.String(tst, "[a]", qu.String())
	chk.String(tst, ToString(qu.Front()), "a")
	chk.String(tst, ToString(qu.Back()), "a")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 1)

	io.PfYel("\nIn(b)\n")
	qu.In(FromString("b"))
	chk.String(tst, "[a b v]", io.Sf("%v", qu.ring))
	chk.String(tst, "[a b]", qu.String())
	chk.String(tst, ToString(qu.Front()), "a")
	chk.String(tst, ToString(qu.Back()), "b")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 2)

	io.PfYel("\nOut(a)\n")
	res = ToString(qu.Out())
	chk.String(tst, res, "a")
	chk.String(tst, "[a b v]", io.Sf("%v", qu.ring))
	chk.String(tst, "[b]", qu.String())
	chk.String(tst, ToString(qu.Front()), "b")
	chk.String(tst, ToString(qu.Back()), "b")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 1)

	io.PfYel("\nIn(a) again\n")
	qu.In(FromString("a"))
	chk.String(tst, "[a b a]", io.Sf("%v", qu.ring))
	chk.String(tst, "[b a]", qu.String())
	chk.String(tst, ToString(qu.Front()), "b")
	chk.String(tst, ToString(qu.Back()), "a")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 2)

	io.PfYel("\nIn(c)\n")
	qu.In(FromString("c"))
	chk.String(tst, "[c b a]", io.Sf("%v", qu.ring))
	chk.String(tst, "[b a c]", qu.String())
	chk.String(tst, ToString(qu.Front()), "b")
	chk.String(tst, ToString(qu.Back()), "c")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 3)

	io.PfYel("\nIn(x)\n")
	qu.In(FromString("x"))
	chk.String(tst, "[b a c x]", io.Sf("%v", qu.ring))
	chk.String(tst, "[b a c x]", qu.String())
	chk.String(tst, ToString(qu.Front()), "b")
	chk.String(tst, ToString(qu.Back()), "x")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 4)

	io.PfYel("\nOut(b)\n")
	res = ToString(qu.Out())
	chk.String(tst, res, "b")
	chk.String(tst, "[b a c x]", io.Sf("%v", qu.ring))
	chk.String(tst, "[a c x]", qu.String())
	chk.String(tst, ToString(qu.Front()), "a")
	chk.String(tst, ToString(qu.Back()), "x")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 3)

	io.PfYel("\nOut(a)\n")
	res = ToString(qu.Out())
	chk.String(tst, res, "a")
	chk.String(tst, "[b a c x]", io.Sf("%v", qu.ring))
	chk.String(tst, "[c x]", qu.String())
	chk.String(tst, ToString(qu.Front()), "c")
	chk.String(tst, ToString(qu.Back()), "x")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 2)

	io.PfYel("\nOut(c)\n")
	res = ToString(qu.Out())
	chk.String(tst, res, "c")
	chk.String(tst, "[b a c x]", io.Sf("%v", qu.ring))
	chk.String(tst, "[x]", qu.String())
	chk.String(tst, ToString(qu.Front()), "x")
	chk.String(tst, ToString(qu.Back()), "x")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 1)

	io.PfYel("\nOut(x)\n")
	res = ToString(qu.Out())
	chk.String(tst, res, "x")
	chk.String(tst, "[b a c x]", io.Sf("%v", qu.ring))
	chk.String(tst, "[]", qu.String())
	chk.Int(tst, "len(queue)", qu.Nmembers(), 0)

	io.PfYel("\nOut(nothing)\n")
	chk.String(tst, "[b a c x]", io.Sf("%v", qu.ring))
	chk.String(tst, "[]", qu.String())
	chk.Int(tst, "len(queue)", qu.Nmembers(), 0)

	io.PfYel("\nIn(i)\n")
	qu.In(FromString("i"))
	chk.String(tst, "[i a c x]", io.Sf("%v", qu.ring))
	chk.String(tst, "[i]", qu.String())
	chk.String(tst, ToString(qu.Front()), "i")
	chk.String(tst, ToString(qu.Back()), "i")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 1)

	io.PfYel("\nIn(j)\n")
	qu.In(FromString("j"))
	chk.String(tst, "[i j c x]", io.Sf("%v", qu.ring))
	chk.String(tst, "[i j]", qu.String())
	chk.String(tst, ToString(qu.Front()), "i")
	chk.String(tst, ToString(qu.Back()), "j")
	chk.Int(tst, "len(queue)", qu.Nmembers(), 2)
}
<|endoftext|>


<commit_before>// Copyright (c) 2014 Datacratic. All rights reserved.

package rest

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"strconv"
	"strings"
	"sync"
	"time"
)

// Client is a convenience REST client which simplifies the creation of REST
// requests.
type Client struct {
	*http.Client

	// Host is the address of the remote REST endpoint where requests should be
	// sent to.
	Host string

	// Root is a prefix that will be preprended to all path requests created by
	// this client.
	Root string

	// Header is a list of HTTP requests that will be added to every requests
	// originating from this client.
	Header http.Header

	// Limit sets a hard limit on the number of concurrent requests. If not set
	// then no limits are imposed.
	Limit uint

	initialize sync.Once

	limit chan struct{}
}

// NewRequest creates a new Request object for the given HTTP method.
func (client *Client) NewRequest(method string) *Request {
	client.initialize.Do(func() {
		if client.Client == nil {
			client.Client = http.DefaultClient
		}

		if client.Limit > 0 {
			client.limit = make(chan struct{})

			for i := uint(0); i < client.Limit; i++ {
				client.end()
			}
		}

	})

	return &Request{
		REST:   client,
		Client: client.Client,
		Host:   client.Host,
		Method: method,
		Root:   client.Root,
		Header: client.Header,
	}
}

func (client *Client) begin() {
	if client.limit != nil {
		<-client.limit
	}
}

func (client *Client) end() {
	if client.limit != nil {
		client.limit <- struct{}{}
	}
}

// Request is used to gradually construct REST requests and send them to a
// remote endpoint. Request object should be created via the NewRequest function
// or the Client.NewRequest function and filled in via the SetXxx and AddXxx
// functions. Finally the request is sent via the Send function which returns a
// Response object.
type Request struct {

	// REST is the client that originated the request. Can be nil.
	REST *Client

	// Client is the http.Client used to send the request. Defaults to
	// http.DefaultClient and can changed via the SetClient method.
	Client *http.Client

	// Host is the address of the remote REST endpoint where requests should be
	// sent to.
	Host string

	// Root is a prefix that will be preprended to all path requests created by
	// this client.
	Root string

	// Path is the absolute path where the Request should be routed to on the
	// remote endpoint. Can be changed via the SetPath method.
	Path string

	// Method is the HTTP verb used for the HTTP request.
	Method string

	// Header contains all the headers to be added to the HTTP request. Can be
	// changed via the AddHeader method.
	Header http.Header

	// Body is the JSON serialized body of the HTTP request. Can be set via the
	// SetBody method.
	Body []byte

	HTTP *http.Request

	err *Error
}

// NewRequest creates a new Request object to be sent to the given host using
// the given HTTP verb.
func NewRequest(host, method string) *Request {
	return &Request{
		Host:   host,
		Method: method,
		Client: http.DefaultClient,
	}
}

// SetClient selects the http.Client to be used to execute the requests.
func (req *Request) SetClient(client *http.Client) *Request {
	req.Client = client
	return req
}

// SetPath formats and sets the path where the request will be routed to. Note
// that the root is prefixed to the path before formatting the string.
func (req *Request) SetPath(path string, args ...interface{}) *Request {
	req.Path = fmt.Sprintf(JoinPath(req.Root, path), args...)
	return req
}

// AddHeader adds the given header to the request.
func (req *Request) AddHeader(key, value string) *Request {
	if req.Header == nil {
		req.Header = make(http.Header)
	}

	req.Header.Add(key, value)
	return req
}

// SetBody marshals the given objects and sets it as the body of the
// request. The Content-Length header will be automatically set.
func (req *Request) SetBody(obj interface{}) *Request {
	var err error
	if req.Body, err = json.Marshal(obj); err == nil {
		req.AddHeader("Content-Length", strconv.Itoa(len(req.Body)))

	} else {
		req.err = &Error{MarshalError, err}
	}

	return req
}

// Send attempts to send the request to the remote endpoint and returns a
// Response which contains the result.
func (req *Request) Send() *Response {
	t0 := time.Now()

	if len(req.Path) == 0 {
		req.Path = req.Root
	}

	resp := &Response{Request: req, Error: req.err}

	if resp.Error == nil {
		if req.REST != nil {
			req.REST.begin()
		}

		req.send(resp)

		if req.REST != nil {
			req.REST.end()
		}
	}

	resp.Latency = time.Since(t0)
	return resp
}

func (req *Request) send(resp *Response) {
	var reader io.Reader
	if len(req.Body) > 0 {
		reader = bytes.NewReader(req.Body)
	}

	url := strings.TrimRight(req.Host, "/") + req.Path

	var err error

	if req.HTTP, err = http.NewRequest(req.Method, url, reader); err != nil {
		resp.Error = &Error{NewRequestError, err}
		return
	}

	req.AddHeader("Content-Type", "application/json")
	req.HTTP.Header = req.Header

	httpResp, err := req.Client.Do(req.HTTP)
	if err != nil {
		resp.Error = &Error{SendRequestError, err}
		return
	}

	resp.Code = httpResp.StatusCode
	resp.Header = httpResp.Header

	if resp.Body, err = ioutil.ReadAll(httpResp.Body); err != nil {
		resp.Error = &Error{ReadBodyError, err}
	}

	httpResp.Body.Close()
	return
}

// Response holds the result of a sent REST request. The response should be read
// via the GetBody method which checks the various fields to detect errors.
type Response struct {

	// Request is the request that originated the response.
	Request *Request

	// Code is the http status code returned by the endpoint.
	Code int

	// Header holds the headers of the HTTP response.
	Header http.Header

	// Body holds the raw unmarshalled body of the HTTP response. GetBody can be
	// used to unmarshal the body.
	Body []byte

	// Error is set if an error occured while sending the request.
	Error *Error

	// Latency indicates how long the request round-trip took.
	Latency time.Duration
}

// GetBody checks the various fields of the response for errors and unmarshals
// the response body if the given object is not nil. If an error is detected,
// the error type and error will be returned instead.
func (resp *Response) GetBody(obj interface{}) (err *Error) {
	if resp.Error != nil {
		err = resp.Error

	} else if resp.Code == http.StatusNotFound {
		err = &Error{UnknownRoute, errors.New(string(resp.Body))}

	} else if resp.Code >= 400 {
		err = &Error{EndpointError, errors.New(string(resp.Body))}

	} else if resp.Code < 200 && resp.Code >= 300 {
		err = ErrorFmt(UnexpectedStatusCode, "unexpected status code: %d", resp.Code)

	} else if resp.Code == http.StatusNoContent {
		if obj == nil {
			return
		}
		err = ErrorFmt(UnexpectedStatusCode, "unexpected status code: 204")

	} else if contentType := resp.Header.Get("Content-Type"); contentType != "application/json" {
		err = ErrorFmt(UnsupportedContentType, "unsupported content-type: '%s' != 'application/json'", contentType)

	} else if jsonErr := json.Unmarshal(resp.Body, obj); err != nil {
		err = &Error{UnmarshalError, jsonErr}
	}

	return
}
<commit_msg>client limits no longer block infinitely.<commit_after>// Copyright (c) 2014 Datacratic. All rights reserved.

package rest

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"strconv"
	"strings"
	"sync"
	"time"
)

// Client is a convenience REST client which simplifies the creation of REST
// requests.
type Client struct {
	*http.Client

	// Host is the address of the remote REST endpoint where requests should be
	// sent to.
	Host string

	// Root is a prefix that will be preprended to all path requests created by
	// this client.
	Root string

	// Header is a list of HTTP requests that will be added to every requests
	// originating from this client.
	Header http.Header

	// Limit sets a hard limit on the number of concurrent requests. If not set
	// then no limits are imposed.
	Limit uint

	initialize sync.Once

	limit chan struct{}
}

// NewRequest creates a new Request object for the given HTTP method.
func (client *Client) NewRequest(method string) *Request {
	client.initialize.Do(func() {
		if client.Client == nil {
			client.Client = http.DefaultClient
		}

		if client.Limit > 0 {
			client.limit = make(chan struct{}, client.Limit)

			for i := uint(0); i < client.Limit; i++ {
				client.end()
			}
		}

	})

	return &Request{
		REST:   client,
		Client: client.Client,
		Host:   client.Host,
		Method: method,
		Root:   client.Root,
		Header: client.Header,
	}
}

func (client *Client) begin() {
	if client.limit != nil {
		<-client.limit
	}
}

func (client *Client) end() {
	if client.limit != nil {
		client.limit <- struct{}{}
	}
}

// Request is used to gradually construct REST requests and send them to a
// remote endpoint. Request object should be created via the NewRequest function
// or the Client.NewRequest function and filled in via the SetXxx and AddXxx
// functions. Finally the request is sent via the Send function which returns a
// Response object.
type Request struct {

	// REST is the client that originated the request. Can be nil.
	REST *Client

	// Client is the http.Client used to send the request. Defaults to
	// http.DefaultClient and can changed via the SetClient method.
	Client *http.Client

	// Host is the address of the remote REST endpoint where requests should be
	// sent to.
	Host string

	// Root is a prefix that will be preprended to all path requests created by
	// this client.
	Root string

	// Path is the absolute path where the Request should be routed to on the
	// remote endpoint. Can be changed via the SetPath method.
	Path string

	// Method is the HTTP verb used for the HTTP request.
	Method string

	// Header contains all the headers to be added to the HTTP request. Can be
	// changed via the AddHeader method.
	Header http.Header

	// Body is the JSON serialized body of the HTTP request. Can be set via the
	// SetBody method.
	Body []byte

	HTTP *http.Request

	err *Error
}

// NewRequest creates a new Request object to be sent to the given host using
// the given HTTP verb.
func NewRequest(host, method string) *Request {
	return &Request{
		Host:   host,
		Method: method,
		Client: http.DefaultClient,
	}
}

// SetClient selects the http.Client to be used to execute the requests.
func (req *Request) SetClient(client *http.Client) *Request {
	req.Client = client
	return req
}

// SetPath formats and sets the path where the request will be routed to. Note
// that the root is prefixed to the path before formatting the string.
func (req *Request) SetPath(path string, args ...interface{}) *Request {
	req.Path = fmt.Sprintf(JoinPath(req.Root, path), args...)
	return req
}

// AddHeader adds the given header to the request.
func (req *Request) AddHeader(key, value string) *Request {
	if req.Header == nil {
		req.Header = make(http.Header)
	}

	req.Header.Add(key, value)
	return req
}

// SetBody marshals the given objects and sets it as the body of the
// request. The Content-Length header will be automatically set.
func (req *Request) SetBody(obj interface{}) *Request {
	var err error
	if req.Body, err = json.Marshal(obj); err == nil {
		req.AddHeader("Content-Length", strconv.Itoa(len(req.Body)))

	} else {
		req.err = &Error{MarshalError, err}
	}

	return req
}

// Send attempts to send the request to the remote endpoint and returns a
// Response which contains the result.
func (req *Request) Send() *Response {
	t0 := time.Now()

	if len(req.Path) == 0 {
		req.Path = req.Root
	}

	resp := &Response{Request: req, Error: req.err}

	if resp.Error == nil {
		if req.REST != nil {
			req.REST.begin()
		}

		req.send(resp)

		if req.REST != nil {
			req.REST.end()
		}
	}

	resp.Latency = time.Since(t0)
	return resp
}

func (req *Request) send(resp *Response) {
	var reader io.Reader
	if len(req.Body) > 0 {
		reader = bytes.NewReader(req.Body)
	}

	url := strings.TrimRight(req.Host, "/") + req.Path

	var err error

	if req.HTTP, err = http.NewRequest(req.Method, url, reader); err != nil {
		resp.Error = &Error{NewRequestError, err}
		return
	}

	req.AddHeader("Content-Type", "application/json")
	req.HTTP.Header = req.Header

	httpResp, err := req.Client.Do(req.HTTP)
	if err != nil {
		resp.Error = &Error{SendRequestError, err}
		return
	}

	resp.Code = httpResp.StatusCode
	resp.Header = httpResp.Header

	if resp.Body, err = ioutil.ReadAll(httpResp.Body); err != nil {
		resp.Error = &Error{ReadBodyError, err}
	}

	httpResp.Body.Close()
	return
}

// Response holds the result of a sent REST request. The response should be read
// via the GetBody method which checks the various fields to detect errors.
type Response struct {

	// Request is the request that originated the response.
	Request *Request

	// Code is the http status code returned by the endpoint.
	Code int

	// Header holds the headers of the HTTP response.
	Header http.Header

	// Body holds the raw unmarshalled body of the HTTP response. GetBody can be
	// used to unmarshal the body.
	Body []byte

	// Error is set if an error occured while sending the request.
	Error *Error

	// Latency indicates how long the request round-trip took.
	Latency time.Duration
}

// GetBody checks the various fields of the response for errors and unmarshals
// the response body if the given object is not nil. If an error is detected,
// the error type and error will be returned instead.
func (resp *Response) GetBody(obj interface{}) (err *Error) {
	if resp.Error != nil {
		err = resp.Error

	} else if resp.Code == http.StatusNotFound {
		err = &Error{UnknownRoute, errors.New(string(resp.Body))}

	} else if resp.Code >= 400 {
		err = &Error{EndpointError, errors.New(string(resp.Body))}

	} else if resp.Code < 200 && resp.Code >= 300 {
		err = ErrorFmt(UnexpectedStatusCode, "unexpected status code: %d", resp.Code)

	} else if resp.Code == http.StatusNoContent {
		if obj == nil {
			return
		}
		err = ErrorFmt(UnexpectedStatusCode, "unexpected status code: 204")

	} else if contentType := resp.Header.Get("Content-Type"); contentType != "application/json" {
		err = ErrorFmt(UnsupportedContentType, "unsupported content-type: '%s' != 'application/json'", contentType)

	} else if jsonErr := json.Unmarshal(resp.Body, obj); err != nil {
		err = &Error{UnmarshalError, jsonErr}
	}

	return
}
<|endoftext|>


<commit_before>// Copyright 2017 The Ebiten Authors
//
// 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 restorable

import (
	"image"
	"image/color"
	"image/draw"
	"runtime"

	"github.com/hajimehoshi/ebiten/internal/math"
)

// CopyImage copies origImg to a new RGBA image.
//
// Basically CopyImage just calls draw.Draw.
// If origImg is a paletted image, an optimized copying method is used.
//
// CopyImage is used only internally but it is exposed for testing.
func CopyImage(origImg image.Image) *image.RGBA {
	size := origImg.Bounds().Size()
	w, h := size.X, size.Y
	newImg := image.NewRGBA(image.Rect(0, 0, math.NextPowerOf2Int(w), math.NextPowerOf2Int(h)))
	switch origImg := origImg.(type) {
	case *image.Paletted:
		b := origImg.Bounds()
		x0 := b.Min.X
		y0 := b.Min.Y
		x1 := b.Max.X
		y1 := b.Max.Y
		palette := make([]uint8, len(origImg.Palette)*4)
		for i, c := range origImg.Palette {
			rgba := color.RGBAModel.Convert(c).(color.RGBA)
			palette[4*i] = rgba.R
			palette[4*i+1] = rgba.G
			palette[4*i+2] = rgba.B
			palette[4*i+3] = rgba.A
		}
		index0 := 0
		index1 := 0
		d0 := origImg.Stride - (x1 - x0)
		d1 := newImg.Stride - (x1-x0)*4
		pix0 := origImg.Pix
		pix1 := newImg.Pix
		for j := 0; j < y1-y0; j++ {
			for i := 0; i < x1-x0; i++ {
				p := int(pix0[index0])
				pix1[index1] = palette[4*p]
				pix1[index1+1] = palette[4*p+1]
				pix1[index1+2] = palette[4*p+2]
				pix1[index1+3] = palette[4*p+3]
				index0++
				index1 += 4
			}
			index0 += d0
			index1 += d1
		}
	default:
		draw.Draw(newImg, image.Rect(0, 0, w, h), origImg, origImg.Bounds().Min, draw.Src)
	}
	runtime.Gosched()
	return newImg
}
<commit_msg>restorable: Remove unneeded NextPowerOf2Int usage<commit_after>// Copyright 2017 The Ebiten Authors
//
// 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 restorable

import (
	"image"
	"image/color"
	"image/draw"
	"runtime"
)

// CopyImage copies origImg to a new RGBA image.
//
// Basically CopyImage just calls draw.Draw.
// If origImg is a paletted image, an optimized copying method is used.
//
// CopyImage is used only internally but it is exposed for testing.
func CopyImage(origImg image.Image) *image.RGBA {
	size := origImg.Bounds().Size()
	w, h := size.X, size.Y
	newImg := image.NewRGBA(image.Rect(0, 0, w, h))
	switch origImg := origImg.(type) {
	case *image.Paletted:
		b := origImg.Bounds()
		x0 := b.Min.X
		y0 := b.Min.Y
		x1 := b.Max.X
		y1 := b.Max.Y
		palette := make([]uint8, len(origImg.Palette)*4)
		for i, c := range origImg.Palette {
			rgba := color.RGBAModel.Convert(c).(color.RGBA)
			palette[4*i] = rgba.R
			palette[4*i+1] = rgba.G
			palette[4*i+2] = rgba.B
			palette[4*i+3] = rgba.A
		}
		index0 := 0
		index1 := 0
		d0 := origImg.Stride - (x1 - x0)
		d1 := newImg.Stride - (x1-x0)*4
		pix0 := origImg.Pix
		pix1 := newImg.Pix
		for j := 0; j < y1-y0; j++ {
			for i := 0; i < x1-x0; i++ {
				p := int(pix0[index0])
				pix1[index1] = palette[4*p]
				pix1[index1+1] = palette[4*p+1]
				pix1[index1+2] = palette[4*p+2]
				pix1[index1+3] = palette[4*p+3]
				index0++
				index1 += 4
			}
			index0 += d0
			index1 += d1
		}
	default:
		draw.Draw(newImg, image.Rect(0, 0, w, h), origImg, origImg.Bounds().Min, draw.Src)
	}
	runtime.Gosched()
	return newImg
}
<|endoftext|>


<commit_before>// Copyright(C) 2022 github.com/fsgo  All Rights Reserved.
// Author: hidu <duv123@gmail.com>
// Date: 2022/11/13

package main

import (
	"flag"
	"io/fs"
	"log"
	"os"
	"os/exec"
	"path/filepath"

	"github.com/fatih/color"
)

var name = flag.String("name", "", "find file name")

func main() {
	flag.Parse()
	if len(*name) == 0 {
		log.Fatalln(color.RedString("-name is required"))
	}
	cmdName := flag.Arg(0)
	if len(cmdName) == 0 {
		log.Fatalln(color.RedString("cmd is empty"))
	}
	var fail int
	err := filepath.Walk("./", func(path string, info fs.FileInfo, err error) error {
		if err != nil {
			return err
		}
		n := filepath.Base(path)
		if n != *name {
			return nil
		}
		dir := filepath.Dir(path)
		cmd := exec.Command(cmdName, flag.Args()[1:]...)
		color.Cyan("Dir: %s Exec: %s", dir, cmd.String())
		cmd.Dir = dir
		cmd.Stdin = os.Stdin
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		if e1 := cmd.Run(); e1 != nil {
			fail++
			color.Red(e1.Error())
		}
		return nil
	})
	if err != nil {
		log.Fatalln(color.RedString(err.Error()))
	}
	if fail > 0 {
		log.Fatalln(color.RedString("total %d tasks failed", fail))
	}
}

func init() {
	color.Output = os.Stderr
}
<commit_msg>update<commit_after>// Copyright(C) 2022 github.com/fsgo  All Rights Reserved.
// Author: hidu <duv123@gmail.com>
// Date: 2022/11/13

package main

import (
	"flag"
	"fmt"
	"io/fs"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"

	"github.com/fatih/color"
)

var name = flag.String("name", "go.mod", "find file name")
var useReg = flag.Bool("e", false, "name as regular expression")

func main() {
	flag.Parse()
	if len(*name) == 0 {
		log.Fatalln(color.RedString("-name is required"))
	}
	cmdName := flag.Arg(0)
	if len(cmdName) == 0 {
		log.Fatalln(color.RedString("cmd is empty"))
	}

	var reg *regexp.Regexp
	if *useReg {
		r, err := regexp.Compile(*name)
		if err != nil {
			log.Fatalln(color.RedString("regexp.Compile(%q): %v", *name, err))
		}
		reg = r
	}

	match := func(fileName string) bool {
		if *useReg {
			return reg.MatchString(fileName)
		}
		return fileName == *name
	}
	var index int
	var fail int
	err := filepath.Walk("./", func(path string, info fs.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if info.IsDir() {
			return nil
		}

		fileName := filepath.Base(path)

		if !match(fileName) {
			return nil
		}
		index++

		dir := filepath.Dir(path)
		cmd := exec.Command(cmdName, flag.Args()[1:]...)

		s0 := color.GreenString("%3d.", index)
		s1 := color.CyanString("Dir: %s, MatchFile: %s", dir, fileName)
		s2 := color.YellowString("Exec: %s", cmd.String())
		fmt.Println(s0, s1, s2)

		cmd.Dir = dir
		cmd.Stdin = os.Stdin
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		if e1 := cmd.Run(); e1 != nil {
			fail++
			color.Red(e1.Error())
		}
		return fs.SkipDir
	})
	if err != nil {
		log.Fatalln(color.RedString(err.Error()))
	}
	if fail > 0 {
		log.Fatalln(color.RedString("total %d tasks failed", fail))
	}
}

func init() {
	color.Output = os.Stderr
}
<|endoftext|>