<commit_before>package dhcp_test

import (
	"net"
	"os"
	"testing"

	"github.com/nanobox-io/nanobox/util/dhcp"
)

// TestMain ...
func TestMain(m *testing.M) {
	dhcp.Flush()
	os.Exit(m.Run())
}

// TestReservingIps ...
func TestReservingIps(t *testing.T) {
	ipOne, err := dhcp.ReserveGlobal()
	if err != nil {
		t.Errorf("unable to reserve ip", err)
	}
	ipTwo, err := dhcp.ReserveGlobal()
	if err != nil {
		t.Errorf("unable to reserve ip", err)
	}
	ipThree, err := dhcp.ReserveLocal()
	if err != nil {
		t.Errorf("unable to reserve ip", err)
	}
	if ipOne.String() != "192.168.99.51" || ipTwo.String() != "192.168.99.52" || ipThree.String() != "172.19.0.2" {
		t.Errorf("incorrect ip addresses", ipOne, ipTwo, ipThree)
	}
}

// TestReturnIP ...
func TestReturnIP(t *testing.T) {
	err := dhcp.ReturnIP(net.ParseIP("192.168.99.50"))
	if err != nil {
		t.Errorf("unable to return ip", err)
	}
	err = dhcp.ReturnIP(net.ParseIP("192.168.99.51"))
	if err != nil {
		t.Errorf("unable to return ip", err)
	}
	err = dhcp.ReturnIP(net.ParseIP("192.168.0.50"))
	if err != nil {
		t.Errorf("unable to return ip", err)
	}
}

// TestReuseIP ...
func TestReuseIP(t *testing.T) {
	one, err := dhcp.ReserveGlobal()
	if err != nil {
		t.Errorf("unable to reserve ip", err)
	}
	ipTwo, err := dhcp.ReserveGlobal()
	if err != nil {
		t.Errorf("unable to reserve ip", err)
	}
	three, err := dhcp.ReserveLocal()
	if err != nil {
		t.Errorf("unable to reserve ip", err)
	}
	err = dhcp.ReturnIP(ipTwo)
	if err != nil {
		t.Errorf("unable to return ip", err)
	}
	ipTwoAgain, err := dhcp.ReserveGlobal()
	if err != nil {
		t.Errorf("unable to reserve ip", err)
	}
	if !ipTwo.Equal(ipTwoAgain) {
		t.Errorf("i should ahve recieved a repeat of %s but i got %s", ipTwo.String(), ipTwoAgain.String())
	}
	dhcp.ReturnIP(one)
	dhcp.ReturnIP(three)
}
<commit_msg>fix test<commit_after>package dhcp_test

import (
	"net"
	"os"
	"testing"

	"github.com/nanobox-io/nanobox/util/dhcp"
)

// TestMain ...
func TestMain(m *testing.M) {
	dhcp.Flush()
	os.Exit(m.Run())
}

// TestReservingIps ...
func TestReservingIps(t *testing.T) {
	ipOne, err := dhcp.ReserveGlobal()
	if err != nil {
		t.Errorf("unable to reserve ip", err)
	}
	ipTwo, err := dhcp.ReserveGlobal()
	if err != nil {
		t.Errorf("unable to reserve ip", err)
	}
	ipThree, err := dhcp.ReserveLocal()
	if err != nil {
		t.Errorf("unable to reserve ip", err)
	}
	if ipOne.String() != "192.168.99.51" || ipTwo.String() != "192.168.99.52" || ipThree.String() != "172.21.0.2" {
		t.Errorf("incorrect ip addresses", ipOne, ipTwo, ipThree)
	}
}

// TestReturnIP ...
func TestReturnIP(t *testing.T) {
	err := dhcp.ReturnIP(net.ParseIP("192.168.99.50"))
	if err != nil {
		t.Errorf("unable to return ip", err)
	}
	err = dhcp.ReturnIP(net.ParseIP("192.168.99.51"))
	if err != nil {
		t.Errorf("unable to return ip", err)
	}
	err = dhcp.ReturnIP(net.ParseIP("192.168.0.50"))
	if err != nil {
		t.Errorf("unable to return ip", err)
	}
}

// TestReuseIP ...
func TestReuseIP(t *testing.T) {
	one, err := dhcp.ReserveGlobal()
	if err != nil {
		t.Errorf("unable to reserve ip", err)
	}
	ipTwo, err := dhcp.ReserveGlobal()
	if err != nil {
		t.Errorf("unable to reserve ip", err)
	}
	three, err := dhcp.ReserveLocal()
	if err != nil {
		t.Errorf("unable to reserve ip", err)
	}
	err = dhcp.ReturnIP(ipTwo)
	if err != nil {
		t.Errorf("unable to return ip", err)
	}
	ipTwoAgain, err := dhcp.ReserveGlobal()
	if err != nil {
		t.Errorf("unable to reserve ip", err)
	}
	if !ipTwo.Equal(ipTwoAgain) {
		t.Errorf("i should ahve recieved a repeat of %s but i got %s", ipTwo.String(), ipTwoAgain.String())
	}
	dhcp.ReturnIP(one)
	dhcp.ReturnIP(three)
}
<|endoftext|>


<commit_before>// Copyright 2014, David Howden
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package numerus is a simple implemetation of Roman Numerals.
package numerus

import (
	"errors"
	"fmt"
	"strings"
)

type numeral interface {
	Value() uint
	String() string
}

type sym struct {
	s string
	v uint
}

func (s sym) Value() uint {
	return s.v
}

func (s sym) String() string {
	return s.s
}

type comb struct {
	a, b sym // NB: a < b
}

func (c comb) Value() uint {
	return c.b.Value() - c.a.Value()
}

func (c comb) String() string {
	return c.a.String() + c.b.String()
}

var (
	_I = sym{"I", 1}
	_V = sym{"V", 5}
	_X = sym{"X", 10}
	_L = sym{"L", 50}
	_C = sym{"C", 100}
	_D = sym{"D", 500}
	_M = sym{"M", 1000}

	_IV = comb{_I, _V}
	_IX = comb{_I, _X}
	_XL = comb{_X, _L}
	_XC = comb{_X, _C}
	_CD = comb{_C, _D}
	_CM = comb{_C, _M}
)

var descNumerals = []numeral{_M, _CM, _D, _CD, _C, _XC, _L, _XL, _X, _IX, _V, _IV, _I}

// Limit is the upper bound of possible numerals allowed by this package
// (this limit is set by the rule which prohibits more than three consecutive Ms).
const Limit = Numeral(3999)

// Numeral represents a Roman Numeral value.
type Numeral uint

// String returns a string representing the underlying Numeral in standard
// Roman Numeral notation.
func (n Numeral) String() string {
	result := ""
	i := uint(n)

	for _, v := range descNumerals {
		for {
			if i < v.Value() {
				break
			}
			result += v.String()
			i -= v.Value()
		}
	}
	return result
}

// Value returns the underlying value of the numeral as a uint.
func (n Numeral) Value() uint {
	return uint(n)
}

// parse takes a string representation of a Roman Numeral (in standard form)
// and returns a uint and error value, which is set if the given input is not
// in the standard representation.
func parse(s string) (uint, error) {
	// As overflowing doesn't catch this, we test for it first
	if strings.Contains(s, "MMMM") {
		return 0, errors.New("invalid numeral near MMMM")
	}

	// Check the running totals so that we don't accept invalid input
	// i.e. MCMD should be MMCD
	check := make([]uint, len(descNumerals))

	n := uint(0)
	buf := s
	for i, v := range descNumerals {
		for {
			if x := strings.TrimPrefix(buf, v.String()); len(x) < len(buf) {
				if i > 0 {
					for j := 0; j < i; j++ {
						check[j] += v.Value()
						if check[j] >= descNumerals[j].Value() {
							return 0, fmt.Errorf("invalid numeral near %v", buf)
						}
					}
				}
				n += v.Value()
				buf = x
			} else {
				break
			}
		}
	}

	if len(buf) > 0 {
		return 0, fmt.Errorf("invalid numeral near %v", buf)
	}
	return n, nil
}

// Parse takes a string in standard Roman Numeral notation and returns a Numeral.
// If the given representation is invalid an error is returned.
func Parse(s string) (Numeral, error) {
	n, err := parse(s)
	if err != nil {
		return Numeral(0), err
	}
	return Numeral(n), err
}
<commit_msg>Simplify main parse loop<commit_after>// Copyright 2014, David Howden
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package numerus is a simple implemetation of Roman Numerals.
package numerus

import (
	"errors"
	"fmt"
	"strings"
)

type numeral interface {
	Value() uint
	String() string
}

type sym struct {
	s string
	v uint
}

func (s sym) Value() uint {
	return s.v
}

func (s sym) String() string {
	return s.s
}

type comb struct {
	a, b sym // NB: a < b
}

func (c comb) Value() uint {
	return c.b.Value() - c.a.Value()
}

func (c comb) String() string {
	return c.a.String() + c.b.String()
}

var (
	_I = sym{"I", 1}
	_V = sym{"V", 5}
	_X = sym{"X", 10}
	_L = sym{"L", 50}
	_C = sym{"C", 100}
	_D = sym{"D", 500}
	_M = sym{"M", 1000}

	_IV = comb{_I, _V}
	_IX = comb{_I, _X}
	_XL = comb{_X, _L}
	_XC = comb{_X, _C}
	_CD = comb{_C, _D}
	_CM = comb{_C, _M}
)

var descNumerals = []numeral{_M, _CM, _D, _CD, _C, _XC, _L, _XL, _X, _IX, _V, _IV, _I}

// Limit is the upper bound of possible numerals allowed by this package
// (this limit is set by the rule which prohibits more than three consecutive Ms).
const Limit = Numeral(3999)

// Numeral represents a Roman Numeral value.
type Numeral uint

// String returns a string representing the underlying Numeral in standard
// Roman Numeral notation.
func (n Numeral) String() string {
	result := ""
	i := uint(n)

	for _, v := range descNumerals {
		for {
			if i < v.Value() {
				break
			}
			result += v.String()
			i -= v.Value()
		}
	}
	return result
}

// Value returns the underlying value of the numeral as a uint.
func (n Numeral) Value() uint {
	return uint(n)
}

// parse takes a string representation of a Roman Numeral (in standard form)
// and returns a uint and error value, which is set if the given input is not
// in the standard representation.
func parse(s string) (uint, error) {
	// As overflowing doesn't catch this, we test for it first
	if strings.Contains(s, "MMMM") {
		return 0, errors.New("invalid numeral near MMMM")
	}

	// Check the running totals so that we don't accept invalid input
	// i.e. MCMD should be MMCD
	check := make([]uint, len(descNumerals))

	n := uint(0)
	buf := s
	for i, v := range descNumerals {
		for {
			vs := v.String()
			if !strings.HasPrefix(buf, vs) {
				break
			}

			for j := 0; j < i; j++ {
				check[j] += v.Value()
				if check[j] >= descNumerals[j].Value() {
					return 0, fmt.Errorf("invalid numeral near %v", buf)
				}
			}
			n += v.Value()
			buf = buf[len(vs):]
		}
	}

	if len(buf) > 0 {
		return 0, fmt.Errorf("invalid numeral near %v", buf)
	}
	return n, nil
}

// Parse takes a string in standard Roman Numeral notation and returns a Numeral.
// If the given representation is invalid an error is returned.
func Parse(s string) (Numeral, error) {
	n, err := parse(s)
	if err != nil {
		return Numeral(0), err
	}
	return Numeral(n), err
}
<|endoftext|>


<commit_before>package nyb

import (
	"encoding/json"
	"fmt"
	"log"
	"sort"
	"sync"
	"time"

	"github.com/hako/durafmt"
	"github.com/ugjka/dumbirc"
)

//Settings for bot
type Settings struct {
	IrcNick    string
	IrcChans   []string
	IrcServer  string
	IrcTrigger string
	IrcUseTLS  bool
	IrcConn    *dumbirc.Connection
	LogChan    LogChan
	Stopper    chan bool
	Email      string
	Nominatim  string
	extra      extra
}

type extra struct {
	zones TZS
	last  TZ
	next  TZ
	start chan bool
	once  sync.Once
	//This is used to prevent sending ping before we
	//have response from previous ping (any activity on irc)
	//pingpong(pp) sends a signal to ping timer
	pp   chan bool
	wait sync.WaitGroup
}

//New creates new bot
func New(nick string, chans []string, trigger string, server string,
	tls bool, email string, nominatim string) *Settings {
	return &Settings{
		nick,
		chans,
		server,
		trigger,
		tls,
		dumbirc.New(nick, "nyebot", server, tls),
		newLogChan(),
		make(chan bool),
		email,
		nominatim,
		extra{
			start: make(chan bool),
			pp:    make(chan bool, 1),
		},
	}
}

var stFinished = "That's it, Year %d is here AoE"

//Start starts the bot
func (s *Settings) Start() {
	log.SetOutput(s.LogChan)
	log.Println("Starting the bot...")

	//To exit gracefully we need to wait
	defer s.extra.wait.Wait()
	//
	//Set up irc
	//
	bot := s.IrcConn
	//Add Callbacs
	s.addCallbacks()
	//Add Triggers
	s.addTriggers()

	//Reconnect logic and Irc Pinger
	s.extra.wait.Add(1)
	go s.ircControl()
	//Start irc
	bot.Start()

	//Starts when joined, see once.Do
	select {
	case <-s.extra.start:
		log.Println("Got start...")
	case <-s.Stopper:
		return
	}
	//Load timezones
	if err := json.Unmarshal([]byte(Zones), &s.extra.zones); err != nil {
		log.Fatal(err)
	}
	//Sort them
	sort.Sort(sort.Reverse(s.extra.zones))

	//Zone Looper
	for {
		s.loopTimeZones()
		select {
		case <-s.Stopper:
			return
		default:
		}
		bot.PrivMsgBulk(s.IrcChans, fmt.Sprintf(stFinished, target.Year()))
		log.Println("All zones finished...")
		target = target.AddDate(1, 0, 0)
		log.Printf("Wrapping target date around to %d\n", target.Year())
	}
}

//Stop stops the bot
func (s *Settings) Stop() {
	select {
	case <-s.Stopper:
		return
	default:
		close(s.Stopper)
	}
}

var reconnectInterval = time.Second * 30
var pingInterval = time.Minute * 1

func (s *Settings) ircControl() {
	bot := s.IrcConn
	var err error
	defer s.extra.wait.Done()
	for {
		timer := time.NewTimer(pingInterval * 1)
		select {
		case err = <-bot.Errchan:
			log.Println("Error:", err)
			log.Println("Recconecting to irc in 30secs...")
			time.AfterFunc(reconnectInterval, func() {
				select {
				case <-s.Stopper:
					return
				default:
					bot.Start()
				}
			})
		case <-s.Stopper:
			timer.Stop()
			log.Println("Stopping the bot...")
			log.Println("Disconnecting...")
			bot.Disconnect()
			return
		//ping timer
		case <-timer.C:
			timer.Stop()
			//pingpong stuff
			select {
			case <-s.extra.pp:
				log.Println("Sending PING...")
				bot.Ping()
			default:
				log.Println("Got no PONG...")
			}
		}

	}
}

var stNextNewYear = "Next New Year in %s in %s"
var stHappyNewYear = "Happy New Year in %s"

func (s *Settings) loopTimeZones() {
	zones := s.extra.zones
	bot := s.IrcConn
	for i := 0; i < len(zones); i++ {
		dur, err := time.ParseDuration(zones[i].Offset + "h")
		if err != nil {
			log.Fatal(err)
		}
		//Check if zone is past target
		s.extra.next = zones[i]
		if i == 0 {
			s.extra.last = zones[len(zones)-1]
		} else {
			s.extra.last = zones[i-1]
		}
		if time.Now().UTC().Add(dur).Before(target) {
			time.Sleep(time.Second * 2)
			log.Println("Zone pending:", zones[i].Offset)
			humandur := durafmt.Parse(target.Sub(time.Now().UTC().Add(dur)))
			msg := fmt.Sprintf(stNextNewYear, removeMilliseconds(humandur), zones[i])
			bot.PrivMsgBulk(s.IrcChans, msg)
			//Wait till Target in Timezone
			timer := NewTimer(target.Sub(time.Now().UTC().Add(dur)))

			select {
			case <-timer.C:
				timer.Stop()
				msg = fmt.Sprintf(stHappyNewYear, zones[i])
				bot.PrivMsgBulk(s.IrcChans, msg)
				log.Println("Announcing zone:", zones[i].Offset)
			case <-s.Stopper:
				timer.Stop()
				return
			}
		}
	}
}
<commit_msg>minor stuff<commit_after>package nyb

import (
	"encoding/json"
	"fmt"
	"log"
	"sort"
	"sync"
	"time"

	"github.com/hako/durafmt"
	"github.com/ugjka/dumbirc"
)

//Settings for bot
type Settings struct {
	IrcNick    string
	IrcChans   []string
	IrcServer  string
	IrcTrigger string
	IrcUseTLS  bool
	IrcConn    *dumbirc.Connection
	LogChan    LogChan
	Stopper    chan bool
	Email      string
	Nominatim  string
	extra      extra
}

type extra struct {
	zones TZS
	last  TZ
	next  TZ
	//We close this when we get WELCOME msg on join in irc
	start chan bool
	once  sync.Once
	//This is used to prevent sending ping before we
	//have response from previous ping (any activity on irc)
	//pingpong(pp) sends a signal to ping timer
	pp   chan bool
	wait sync.WaitGroup
}

//New creates new bot
func New(nick string, chans []string, trigger string, server string,
	tls bool, email string, nominatim string) *Settings {
	return &Settings{
		nick,
		chans,
		server,
		trigger,
		tls,
		dumbirc.New(nick, "nyebot", server, tls),
		newLogChan(),
		make(chan bool),
		email,
		nominatim,
		extra{
			start: make(chan bool),
			pp:    make(chan bool, 1),
		},
	}
}

var stFinished = "That's it, Year %d is here AoE"

//Start starts the bot
func (s *Settings) Start() {
	log.SetOutput(s.LogChan)
	log.Println("Starting the bot...")

	//To exit gracefully we need to wait
	defer s.extra.wait.Wait()
	//
	//Set up irc
	//
	bot := s.IrcConn
	//Add Callbacs
	s.addCallbacks()
	//Add Triggers
	s.addTriggers()

	//Reconnect logic and Irc Pinger
	s.extra.wait.Add(1)
	go s.ircControl()
	//Start irc
	bot.Start()

	//Starts when joined, see once.Do
	select {
	case <-s.extra.start:
		log.Println("Got start...")
	case <-s.Stopper:
		return
	}
	//Load timezones
	if err := json.Unmarshal([]byte(Zones), &s.extra.zones); err != nil {
		log.Fatal(err)
	}
	//Sort them
	sort.Sort(sort.Reverse(s.extra.zones))

	//Zone Looper
	for {
		s.loopTimeZones()
		select {
		case <-s.Stopper:
			return
		default:
		}
		bot.PrivMsgBulk(s.IrcChans, fmt.Sprintf(stFinished, target.Year()))
		log.Println("All zones finished...")
		target = target.AddDate(1, 0, 0)
		log.Printf("Wrapping the target date around to %d\n", target.Year())
	}
}

//Stop stops the bot
func (s *Settings) Stop() {
	select {
	case <-s.Stopper:
		return
	default:
		close(s.Stopper)
	}
}

var reconnectInterval = time.Second * 30
var pingInterval = time.Minute * 1

func (s *Settings) ircControl() {
	bot := s.IrcConn
	defer s.extra.wait.Done()
	for {
		timer := time.NewTimer(pingInterval * 1)
		select {
		case err := <-bot.Errchan:
			log.Println("Error:", err)
			log.Printf("Reconnecting to irc in %s...\n", reconnectInterval)
			time.AfterFunc(reconnectInterval, func() {
				select {
				case <-s.Stopper:
					return
				default:
					bot.Start()
				}
			})
		case <-s.Stopper:
			timer.Stop()
			log.Println("Stopping the bot...")
			log.Println("Disconnecting...")
			bot.Disconnect()
			return
		//ping timer
		case <-timer.C:
			timer.Stop()
			//pingpong stuff
			select {
			case <-s.extra.pp:
				log.Println("Sending PING...")
				bot.Ping()
			default:
				log.Println("Got no PONG...")
			}
		}

	}
}

var stNextNewYear = "Next New Year in %s in %s"
var stHappyNewYear = "Happy New Year in %s"

func (s *Settings) loopTimeZones() {
	zones := s.extra.zones
	bot := s.IrcConn
	for i := 0; i < len(zones); i++ {
		dur, err := time.ParseDuration(zones[i].Offset + "h")
		if err != nil {
			log.Fatal(err)
		}
		//Check if zone is past target
		s.extra.next = zones[i]
		if i == 0 {
			s.extra.last = zones[len(zones)-1]
		} else {
			s.extra.last = zones[i-1]
		}
		if time.Now().UTC().Add(dur).Before(target) {
			time.Sleep(time.Second * 2)
			log.Println("Zone pending:", zones[i].Offset)
			humandur := durafmt.Parse(target.Sub(time.Now().UTC().Add(dur)))
			msg := fmt.Sprintf(stNextNewYear, removeMilliseconds(humandur), zones[i])
			bot.PrivMsgBulk(s.IrcChans, msg)
			//Wait till Target in Timezone
			timer := NewTimer(target.Sub(time.Now().UTC().Add(dur)))

			select {
			case <-timer.C:
				timer.Stop()
				msg = fmt.Sprintf(stHappyNewYear, zones[i])
				bot.PrivMsgBulk(s.IrcChans, msg)
				log.Println("Announcing zone:", zones[i].Offset)
			case <-s.Stopper:
				timer.Stop()
				return
			}
		}
	}
}
<|endoftext|>


<commit_before>// Copyright 2018 PingCAP, Inc.
//
// 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 memory

import (
	"sync"
	"time"

	"github.com/pingcap/tidb/parser/terror"
	"github.com/pingcap/tidb/util/cgroup"
	"github.com/shirou/gopsutil/v3/mem"
)

// MemTotal returns the total amount of RAM on this system
var MemTotal func() (uint64, error)

// MemUsed returns the total used amount of RAM on this system
var MemUsed func() (uint64, error)

// GetMemTotalIgnoreErr returns the total amount of RAM on this system/container. If error occurs, return 0.
func GetMemTotalIgnoreErr() uint64 {
	if memTotal, err := MemTotal(); err == nil {
		return memTotal
	}
	return 0
}

// MemTotalNormal returns the total amount of RAM on this system in non-container environment.
func MemTotalNormal() (uint64, error) {
	total, t := memLimit.get()
	if time.Since(t) < 60*time.Second {
		return total, nil
	}
	v, err := mem.VirtualMemory()
	if err != nil {
		return v.Total, err
	}
	memLimit.set(v.Total, time.Now())
	return v.Total, nil
}

// MemUsedNormal returns the total used amount of RAM on this system in non-container environment.
func MemUsedNormal() (uint64, error) {
	used, t := memUsage.get()
	if time.Since(t) < 500*time.Millisecond {
		return used, nil
	}
	v, err := mem.VirtualMemory()
	if err != nil {
		return v.Used, err
	}
	memUsage.set(v.Used, time.Now())
	return v.Used, nil
}

type memInfoCache struct {
	updateTime time.Time
	mu         *sync.RWMutex
	mem        uint64
}

func (c *memInfoCache) get() (memo uint64, t time.Time) {
	c.mu.RLock()
	defer c.mu.RUnlock()
	memo, t = c.mem, c.updateTime
	return
}

func (c *memInfoCache) set(memo uint64, t time.Time) {
	c.mu.Lock()
	defer c.mu.Unlock()
	c.mem, c.updateTime = memo, t
}

// expiration time is 60s
var memLimit *memInfoCache

// expiration time is 500ms
var memUsage *memInfoCache

// expiration time is 500ms
// save the memory usage of the server process
var serverMemUsage *memInfoCache

// MemTotalCGroup returns the total amount of RAM on this system in container environment.
func MemTotalCGroup() (uint64, error) {
	memo, t := memLimit.get()
	if time.Since(t) < 60*time.Second {
		return memo, nil
	}
	memo, err := cgroup.GetMemoryLimit()
	if err != nil {
		return memo, err
	}
	memLimit.set(memo, time.Now())
	return memo, nil
}

// MemUsedCGroup returns the total used amount of RAM on this system in container environment.
func MemUsedCGroup() (uint64, error) {
	memo, t := memUsage.get()
	if time.Since(t) < 500*time.Millisecond {
		return memo, nil
	}
	memo, err := cgroup.GetMemoryUsage()
	if err != nil {
		return memo, err
	}
	memUsage.set(memo, time.Now())
	return memo, nil
}

func init() {
	if cgroup.InContainer() {
		MemTotal = MemTotalCGroup
		MemUsed = MemUsedCGroup
	} else {
		MemTotal = MemTotalNormal
		MemUsed = MemUsedNormal
	}
	memLimit = &memInfoCache{
		mu: &sync.RWMutex{},
	}
	memUsage = &memInfoCache{
		mu: &sync.RWMutex{},
	}
	serverMemUsage = &memInfoCache{
		mu: &sync.RWMutex{},
	}
	_, err := MemTotal()
	terror.MustNil(err)
	_, err = MemUsed()
	terror.MustNil(err)
}

// InstanceMemUsed returns the memory usage of this TiDB server
func InstanceMemUsed() (uint64, error) {
	used, t := serverMemUsage.get()
	if time.Since(t) < 500*time.Millisecond {
		return used, nil
	}
	var memoryUsage uint64
	instanceStats := ReadMemStats()
	memoryUsage = instanceStats.HeapAlloc
	serverMemUsage.set(memoryUsage, time.Now())
	return memoryUsage, nil
}
<commit_msg>cgroup: get right value when cgroup set max value (#38661)<commit_after>// Copyright 2018 PingCAP, Inc.
//
// 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 memory

import (
	"sync"
	"time"

	"github.com/pingcap/tidb/parser/terror"
	"github.com/pingcap/tidb/util/cgroup"
	"github.com/pingcap/tidb/util/mathutil"
	"github.com/shirou/gopsutil/v3/mem"
)

// MemTotal returns the total amount of RAM on this system
var MemTotal func() (uint64, error)

// MemUsed returns the total used amount of RAM on this system
var MemUsed func() (uint64, error)

// GetMemTotalIgnoreErr returns the total amount of RAM on this system/container. If error occurs, return 0.
func GetMemTotalIgnoreErr() uint64 {
	if memTotal, err := MemTotal(); err == nil {
		return memTotal
	}
	return 0
}

// MemTotalNormal returns the total amount of RAM on this system in non-container environment.
func MemTotalNormal() (uint64, error) {
	total, t := memLimit.get()
	if time.Since(t) < 60*time.Second {
		return total, nil
	}
	v, err := mem.VirtualMemory()
	if err != nil {
		return v.Total, err
	}
	memLimit.set(v.Total, time.Now())
	return v.Total, nil
}

// MemUsedNormal returns the total used amount of RAM on this system in non-container environment.
func MemUsedNormal() (uint64, error) {
	used, t := memUsage.get()
	if time.Since(t) < 500*time.Millisecond {
		return used, nil
	}
	v, err := mem.VirtualMemory()
	if err != nil {
		return v.Used, err
	}
	memUsage.set(v.Used, time.Now())
	return v.Used, nil
}

type memInfoCache struct {
	updateTime time.Time
	mu         *sync.RWMutex
	mem        uint64
}

func (c *memInfoCache) get() (memo uint64, t time.Time) {
	c.mu.RLock()
	defer c.mu.RUnlock()
	memo, t = c.mem, c.updateTime
	return
}

func (c *memInfoCache) set(memo uint64, t time.Time) {
	c.mu.Lock()
	defer c.mu.Unlock()
	c.mem, c.updateTime = memo, t
}

// expiration time is 60s
var memLimit *memInfoCache

// expiration time is 500ms
var memUsage *memInfoCache

// expiration time is 500ms
// save the memory usage of the server process
var serverMemUsage *memInfoCache

// MemTotalCGroup returns the total amount of RAM on this system in container environment.
func MemTotalCGroup() (uint64, error) {
	memo, t := memLimit.get()
	if time.Since(t) < 60*time.Second {
		return memo, nil
	}
	memo, err := cgroup.GetMemoryLimit()
	if err != nil {
		return memo, err
	}
	v, err := mem.VirtualMemory()
	if err != nil {
		return 0, err
	}
	memo = mathutil.Min(v.Total, memo)
	memLimit.set(memo, time.Now())
	return memo, nil
}

// MemUsedCGroup returns the total used amount of RAM on this system in container environment.
func MemUsedCGroup() (uint64, error) {
	memo, t := memUsage.get()
	if time.Since(t) < 500*time.Millisecond {
		return memo, nil
	}
	memo, err := cgroup.GetMemoryUsage()
	if err != nil {
		return memo, err
	}
	v, err := mem.VirtualMemory()
	if err != nil {
		return 0, err
	}
	memo = mathutil.Min(v.Used, memo)
	memUsage.set(memo, time.Now())
	return memo, nil
}

func init() {
	if cgroup.InContainer() {
		MemTotal = MemTotalCGroup
		MemUsed = MemUsedCGroup
	} else {
		MemTotal = MemTotalNormal
		MemUsed = MemUsedNormal
	}
	memLimit = &memInfoCache{
		mu: &sync.RWMutex{},
	}
	memUsage = &memInfoCache{
		mu: &sync.RWMutex{},
	}
	serverMemUsage = &memInfoCache{
		mu: &sync.RWMutex{},
	}
	_, err := MemTotal()
	terror.MustNil(err)
	_, err = MemUsed()
	terror.MustNil(err)
}

// InstanceMemUsed returns the memory usage of this TiDB server
func InstanceMemUsed() (uint64, error) {
	used, t := serverMemUsage.get()
	if time.Since(t) < 500*time.Millisecond {
		return used, nil
	}
	var memoryUsage uint64
	instanceStats := ReadMemStats()
	memoryUsage = instanceStats.HeapAlloc
	serverMemUsage.set(memoryUsage, time.Now())
	return memoryUsage, nil
}
<|endoftext|>


<commit_before>// Copyright 2012, 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package jujuc

import (
	"fmt"
	"strings"

	"github.com/juju/errors"

	"github.com/juju/cmd"
	"launchpad.net/gnuflag"
)

// RelationSetCommand implements the relation-set command.
type RelationSetCommand struct {
	cmd.CommandBase
	ctx        Context
	RelationId int
	Settings   map[string]string
	formatFlag string // deprecated
}

func NewRelationSetCommand(ctx Context) cmd.Command {
	return &RelationSetCommand{ctx: ctx, Settings: map[string]string{}}
}

func (c *RelationSetCommand) Info() *cmd.Info {
	return &cmd.Info{
		Name:    "relation-set",
		Args:    "key=value [key=value ...]",
		Purpose: "set relation settings",
	}
}

func (c *RelationSetCommand) SetFlags(f *gnuflag.FlagSet) {
	f.Var(newRelationIdValue(c.ctx, &c.RelationId), "r", "specify a relation by id")
	f.StringVar(&c.formatFlag, "format", "", "deprecated format flag")
}

func (c *RelationSetCommand) Init(args []string) error {
	if c.RelationId == -1 {
		return fmt.Errorf("no relation id specified")
	}
	for _, kv := range args {
		parts := strings.SplitN(kv, "=", 2)
		if len(parts) != 2 || len(parts[0]) == 0 {
			return fmt.Errorf(`expected "key=value", got %q`, kv)
		}
		c.Settings[parts[0]] = parts[1]
	}
	return nil
}

func (c *RelationSetCommand) Run(ctx *cmd.Context) (err error) {
	if c.formatFlag != "" {
		fmt.Fprintf(ctx.Stderr, "--format flag deprecated for command %q", c.Info().Name)
	}
	r, found := c.ctx.Relation(c.RelationId)
	if !found {
		return fmt.Errorf("unknown relation id")
	}
	settings, err := r.Settings()
	if err != nil {
		return errors.Annotate(err, "cannot read relation settings")
	}
	for k, v := range c.Settings {
		if v != "" {
			settings.Set(k, v)
		} else {
			settings.Delete(k)
		}
	}
	return nil
}
<commit_msg>Formatting<commit_after>// Copyright 2012, 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package jujuc

import (
	"fmt"
	"strings"

	"github.com/juju/errors"
	"github.com/juju/cmd"
	"launchpad.net/gnuflag"
)

// RelationSetCommand implements the relation-set command.
type RelationSetCommand struct {
	cmd.CommandBase
	ctx        Context
	RelationId int
	Settings   map[string]string
	formatFlag string // deprecated
}

func NewRelationSetCommand(ctx Context) cmd.Command {
	return &RelationSetCommand{ctx: ctx, Settings: map[string]string{}}
}

func (c *RelationSetCommand) Info() *cmd.Info {
	return &cmd.Info{
		Name:    "relation-set",
		Args:    "key=value [key=value ...]",
		Purpose: "set relation settings",
	}
}

func (c *RelationSetCommand) SetFlags(f *gnuflag.FlagSet) {
	f.Var(newRelationIdValue(c.ctx, &c.RelationId), "r", "specify a relation by id")
	f.StringVar(&c.formatFlag, "format", "", "deprecated format flag")
}

func (c *RelationSetCommand) Init(args []string) error {
	if c.RelationId == -1 {
		return fmt.Errorf("no relation id specified")
	}
	for _, kv := range args {
		parts := strings.SplitN(kv, "=", 2)
		if len(parts) != 2 || len(parts[0]) == 0 {
			return fmt.Errorf(`expected "key=value", got %q`, kv)
		}
		c.Settings[parts[0]] = parts[1]
	}
	return nil
}

func (c *RelationSetCommand) Run(ctx *cmd.Context) (err error) {
	if c.formatFlag != "" {
		fmt.Fprintf(ctx.Stderr, "--format flag deprecated for command %q", c.Info().Name)
	}
	r, found := c.ctx.Relation(c.RelationId)
	if !found {
		return fmt.Errorf("unknown relation id")
	}
	settings, err := r.Settings()
	if err != nil {
		return errors.Annotate(err, "cannot read relation settings")
	}
	for k, v := range c.Settings {
		if v != "" {
			settings.Set(k, v)
		} else {
			settings.Delete(k)
		}
	}
	return nil
}
<|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 ode implements solvers for ordinary differential equations, including explicit and
// implicit Runge-Kutta methods; e.g. the fantastic Radau5 method by
// Hairer, Norsett & Wanner [1, 2].
//   References:
//     [1] Hairer E, Nørsett SP, Wanner G (1993). Solving Ordinary Differential Equations I:
//         Nonstiff Problems. Springer Series in Computational Mathematics, Vol. 8, Berlin,
//         Germany, 523 p.
//     [2] Hairer E, Wanner G (1996). Solving Ordinary Differential Equations II: Stiff and
//         Differential-Algebraic Problems. Springer Series in Computational Mathematics,
//         Vol. 14, Berlin, Germany, 614 p.
package ode

import (
	"github.com/cpmech/gosl/chk"
	"github.com/cpmech/gosl/io"
	"github.com/cpmech/gosl/la"
	"github.com/cpmech/gosl/utl"
)

// Solver implements an ODE solver
type Solver struct {

	// main
	Conf *Config // configuration parameters
	Stat *Stat   // statistics
	Out  *Output // output

	// input
	ndim int  // size of y
	fcn  Func // dy/dx := f(x,y)
	jac  JacF // Jacobian: df/dy

	// method, info and workspace
	rkm       rkmethod // Runge-Kutta method
	fixedOnly bool     // method can only be used with fixed steps
	implicit  bool     // method is implicit
	work      *rkwork  // Runge-Kutta workspace
}

// NewSolver returns a new ODE structure with default values and allocated slices
//  NOTE: remember to call Free() to release allocated resources (e.g. from the linear solvers)
func NewSolver(conf *Config, ndim int, fcn Func, jac JacF, M *la.Triplet, ofcn OutF) (o *Solver, err error) {

	// main
	o = new(Solver)
	o.Conf = conf
	o.Stat = NewStat()
	o.Out = NewOutput(ofcn)
	if conf.SaveXY {
		o.Out.Resize(conf.NmaxSS + 1)
	}

	// input
	o.ndim = ndim
	o.fcn = fcn
	o.jac = jac

	// method and info
	o.rkm, err = newRKmethod(o.Conf.Method)
	if err != nil {
		return
	}
	err = o.rkm.Init(o.Conf, ndim, fcn, jac, M)
	if err != nil {
		return
	}

	// information
	var nstg int
	o.fixedOnly, o.implicit, nstg = o.rkm.Info()

	// workspace
	o.work = newRKwork(nstg, o.ndim)
	return
}

// Free releases allocated memory (e.g. by the linear solvers)
func (o *Solver) Free() {
	if o.rkm != nil {
		o.rkm.Free()
	}
}

// Solve solves dy/dx = f(x,y) from x to xf with initial y given in y
func (o *Solver) Solve(y la.Vector, x, xf float64) (err error) {

	// check
	if xf < x {
		err = chk.Err("xf == %v must be greater than x == %v\n", xf, x)
		return
	}

	// initial step size
	h := xf - x
	fixed := false
	if o.Conf.FixedStp > 0 || o.fixedOnly {
		if o.Conf.FixedStp < o.Conf.Hmin {
			o.Conf.FixedStp = o.Conf.IniH
		}
		h = utl.Min(h, o.Conf.FixedStp)
		fixed = true
	} else {
		h = utl.Min(h, o.Conf.IniH)
	}

	// stat and output
	o.Stat.Reset()
	o.Stat.Hopt = h
	o.Out.Execute(h, x, y)

	// set control flags
	o.work.first = true

	// first scaling variable
	la.VecScaleAbs(o.work.scal, o.Conf.atol, o.Conf.rtol, y) // scal = atol + rtol * abs(y)

	// fixed steps //////////////////////////////
	if fixed {
		if o.Conf.Verbose {
			io.Pfgreen("x = %v\n", x)
			io.Pf("y = %v\n", y)
		}
		for x < xf {
			if o.implicit && o.jac == nil { // f0 for numerical Jacobian
				o.Stat.Nfeval++
				o.fcn(o.work.f0, h, x, y)
			}
			_, err = o.rkm.Step(h, x, y, o.Stat, o.work)
			if err != nil {
				return
			}
			o.Stat.Nsteps++
			o.work.first = false
			x += h
			o.rkm.Accept(y, o.work)
			o.Out.Execute(h, x, y)
			if o.Conf.Verbose {
				io.Pfgreen("x = %v\n", x)
				io.Pf("y = %v\n", y)
			}
		}
		return
	}

	// variable steps //////////////////////////////

	// control variables
	o.work.reuseJdec = false
	o.work.reuseJ = false
	o.work.jacIsOK = false
	o.work.hprev = h
	o.work.nit = 0
	o.work.eta = 1.0
	o.work.theta = o.Conf.ThetaMax
	o.work.dvfac = 0.0
	o.work.diverg = false
	o.work.reject = false

	// first function evaluation
	o.Stat.Nfeval++
	o.fcn(o.work.f0, h, x, y) // o.f0 := f(x,y)

	// time loop
	Δx := xf - x
	var dxmax, xstep, div, dxnew, oldH, oldRerr, dxratio, rerr float64
	var last, failed bool
	for x < xf {
		dxmax, xstep = Δx, x+Δx
		failed = false
		for iss := 0; iss < o.Conf.NmaxSS+1; iss++ {

			// total number of substeps
			o.Stat.Nsteps++

			// error: did not converge
			if iss == o.Conf.NmaxSS {
				failed = true
				break
			}

			// converged?
			if x-xstep >= 0.0 {
				break
			}

			// step update
			rerr, err = o.rkm.Step(h, x, y, o.Stat, o.work)

			// iterations diverging ?
			if o.work.diverg {
				o.work.diverg = false
				o.work.reject = true
				last = false
				h *= o.work.dvfac
				continue
			}

			// step size change
			dxnew, div = o.Conf.dxnew(h, rerr, o.work.nit)

			// accepted
			if rerr < 1.0 {

				// set flags
				o.Stat.Naccepted++
				o.work.first = false
				o.work.jacIsOK = false

				// update x and y
				o.work.hprev = h
				x += h
				o.rkm.Accept(y, o.work)

				// output
				o.Out.Execute(h, x, y)

				// converged ?
				if last {
					o.Stat.Hopt = h // optimal h
					break
				}

				// predictive controller of Gustafsson
				if o.Conf.PredCtrl {
					if o.Stat.Naccepted > 1 {
						dxnew = o.Conf.dxnewGus(div, oldH, h, oldRerr, rerr)
					}
					oldH = h
					oldRerr = utl.Max(1.0e-2, rerr)
				}

				// calc new scal and f0
				la.VecScaleAbs(o.work.scal, o.Conf.atol, o.Conf.rtol, y)
				o.Stat.Nfeval++
				o.fcn(o.work.f0, h, x, y) // o.f0 := f(x,y)

				// new step size
				dxnew = utl.Min(dxnew, dxmax)
				if o.work.reject { // do not alow h to grow if previous was a reject
					dxnew = utl.Min(h, dxnew)
				}
				o.work.reject = false

				// do not reuse current Jacobian and decomposition by default
				o.work.reuseJdec = false

				// last step ?
				if x+dxnew-xstep >= 0.0 {
					last = true
					h = xstep - x
				} else {
					dxratio = dxnew / h
					o.work.reuseJdec = o.work.theta <= o.Conf.ThetaMax && dxratio >= o.Conf.C1h && dxratio <= o.Conf.C2h
					if !o.work.reuseJdec {
						h = dxnew
					}
				}

				// check θ to decide if at least the Jacobian can be reused
				if !o.work.reuseJdec {
					o.work.reuseJ = o.work.theta <= o.Conf.ThetaMax
				}

				// rejected
			} else {

				// set flags
				if o.Stat.Naccepted > 0 {
					o.Stat.Nrejected++
				}
				o.work.reject = true
				last = false

				// new step size
				if o.work.first {
					h = 0.1 * h
				} else {
					h = dxnew
				}

				// last step
				if x+h > xstep {
					h = xstep - x
				}
			}
		}

		// sub-stepping failed
		if failed {
			err = chk.Err("substepping did not converge after %d steps\n", o.Conf.NmaxSS)
			break
		}
	}
	return
}
<commit_msg>Fix comment<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 ode implements solvers for ordinary differential equations, including explicit and
// implicit Runge-Kutta methods; e.g. the fantastic Radau5 method by
// Hairer, Norsett & Wanner [1, 2].
//   References:
//     [1] Hairer E, Nørsett SP, Wanner G (1993). Solving Ordinary Differential Equations I:
//         Nonstiff Problems. Springer Series in Computational Mathematics, Vol. 8, Berlin,
//         Germany, 523 p.
//     [2] Hairer E, Wanner G (1996). Solving Ordinary Differential Equations II: Stiff and
//         Differential-Algebraic Problems. Springer Series in Computational Mathematics,
//         Vol. 14, Berlin, Germany, 614 p.
package ode

import (
	"github.com/cpmech/gosl/chk"
	"github.com/cpmech/gosl/io"
	"github.com/cpmech/gosl/la"
	"github.com/cpmech/gosl/utl"
)

// Solver implements an ODE solver
type Solver struct {

	// main
	Conf *Config // configuration parameters
	Stat *Stat   // statistics
	Out  *Output // output

	// input
	ndim int  // size of y
	fcn  Func // dy/dx := f(x,y)
	jac  JacF // Jacobian: df/dy

	// method, info and workspace
	rkm       rkmethod // Runge-Kutta method
	fixedOnly bool     // method can only be used with fixed steps
	implicit  bool     // method is implicit
	work      *rkwork  // Runge-Kutta workspace
}

// NewSolver returns a new ODE structure with default values and allocated slices
//  NOTE: remember to call Free() to release allocated resources (e.g. from the linear solvers)
func NewSolver(conf *Config, ndim int, fcn Func, jac JacF, M *la.Triplet, ofcn OutF) (o *Solver, err error) {

	// main
	o = new(Solver)
	o.Conf = conf
	o.Stat = NewStat()
	o.Out = NewOutput(ofcn)
	if conf.SaveXY {
		o.Out.Resize(conf.NmaxSS + 1)
	}

	// input
	o.ndim = ndim
	o.fcn = fcn
	o.jac = jac

	// method
	o.rkm, err = newRKmethod(o.Conf.Method)
	if err != nil {
		return
	}
	err = o.rkm.Init(o.Conf, ndim, fcn, jac, M)
	if err != nil {
		return
	}

	// information
	var nstg int
	o.fixedOnly, o.implicit, nstg = o.rkm.Info()

	// workspace
	o.work = newRKwork(nstg, o.ndim)
	return
}

// Free releases allocated memory (e.g. by the linear solvers)
func (o *Solver) Free() {
	if o.rkm != nil {
		o.rkm.Free()
	}
}

// Solve solves dy/dx = f(x,y) from x to xf with initial y given in y
func (o *Solver) Solve(y la.Vector, x, xf float64) (err error) {

	// check
	if xf < x {
		err = chk.Err("xf=%v must be greater than x=%v\n", xf, x)
		return
	}

	// initial step size
	h := xf - x
	fixed := false
	if o.Conf.FixedStp > 0 || o.fixedOnly {
		if o.Conf.FixedStp < o.Conf.Hmin {
			o.Conf.FixedStp = o.Conf.IniH
		}
		h = utl.Min(h, o.Conf.FixedStp)
		fixed = true
	} else {
		h = utl.Min(h, o.Conf.IniH)
	}

	// stat and output
	o.Stat.Reset()
	o.Stat.Hopt = h
	o.Out.Execute(h, x, y)

	// set control flags
	o.work.first = true

	// first scaling variable
	la.VecScaleAbs(o.work.scal, o.Conf.atol, o.Conf.rtol, y) // scal = atol + rtol * abs(y)

	// fixed steps //////////////////////////////
	if fixed {
		if o.Conf.Verbose {
			io.Pfgreen("x = %v\n", x)
			io.Pf("y = %v\n", y)
		}
		for x < xf {
			if o.implicit && o.jac == nil { // f0 for numerical Jacobian
				o.Stat.Nfeval++
				o.fcn(o.work.f0, h, x, y)
			}
			_, err = o.rkm.Step(h, x, y, o.Stat, o.work)
			if err != nil {
				return
			}
			o.Stat.Nsteps++
			o.work.first = false
			x += h
			o.rkm.Accept(y, o.work)
			o.Out.Execute(h, x, y)
			if o.Conf.Verbose {
				io.Pfgreen("x = %v\n", x)
				io.Pf("y = %v\n", y)
			}
		}
		return
	}

	// variable steps //////////////////////////////

	// control variables
	o.work.reuseJdec = false
	o.work.reuseJ = false
	o.work.jacIsOK = false
	o.work.hprev = h
	o.work.nit = 0
	o.work.eta = 1.0
	o.work.theta = o.Conf.ThetaMax
	o.work.dvfac = 0.0
	o.work.diverg = false
	o.work.reject = false

	// first function evaluation
	o.Stat.Nfeval++
	o.fcn(o.work.f0, h, x, y) // o.f0 := f(x,y)

	// time loop
	Δx := xf - x
	var dxmax, xstep, div, dxnew, oldH, oldRerr, dxratio, rerr float64
	var last, failed bool
	for x < xf {
		dxmax, xstep = Δx, x+Δx
		failed = false
		for iss := 0; iss < o.Conf.NmaxSS+1; iss++ {

			// total number of substeps
			o.Stat.Nsteps++

			// error: did not converge
			if iss == o.Conf.NmaxSS {
				failed = true
				break
			}

			// converged?
			if x-xstep >= 0.0 {
				break
			}

			// step update
			rerr, err = o.rkm.Step(h, x, y, o.Stat, o.work)

			// iterations diverging ?
			if o.work.diverg {
				o.work.diverg = false
				o.work.reject = true
				last = false
				h *= o.work.dvfac
				continue
			}

			// step size change
			dxnew, div = o.Conf.dxnew(h, rerr, o.work.nit)

			// accepted
			if rerr < 1.0 {

				// set flags
				o.Stat.Naccepted++
				o.work.first = false
				o.work.jacIsOK = false

				// update x and y
				o.work.hprev = h
				x += h
				o.rkm.Accept(y, o.work)

				// output
				o.Out.Execute(h, x, y)

				// converged ?
				if last {
					o.Stat.Hopt = h // optimal h
					break
				}

				// predictive controller of Gustafsson
				if o.Conf.PredCtrl {
					if o.Stat.Naccepted > 1 {
						dxnew = o.Conf.dxnewGus(div, oldH, h, oldRerr, rerr)
					}
					oldH = h
					oldRerr = utl.Max(1.0e-2, rerr)
				}

				// calc new scal and f0
				la.VecScaleAbs(o.work.scal, o.Conf.atol, o.Conf.rtol, y)
				o.Stat.Nfeval++
				o.fcn(o.work.f0, h, x, y) // o.f0 := f(x,y)

				// new step size
				dxnew = utl.Min(dxnew, dxmax)
				if o.work.reject { // do not alow h to grow if previous was a reject
					dxnew = utl.Min(h, dxnew)
				}
				o.work.reject = false

				// do not reuse current Jacobian and decomposition by default
				o.work.reuseJdec = false

				// last step ?
				if x+dxnew-xstep >= 0.0 {
					last = true
					h = xstep - x
				} else {
					dxratio = dxnew / h
					o.work.reuseJdec = o.work.theta <= o.Conf.ThetaMax && dxratio >= o.Conf.C1h && dxratio <= o.Conf.C2h
					if !o.work.reuseJdec {
						h = dxnew
					}
				}

				// check θ to decide if at least the Jacobian can be reused
				if !o.work.reuseJdec {
					o.work.reuseJ = o.work.theta <= o.Conf.ThetaMax
				}

				// rejected
			} else {

				// set flags
				if o.Stat.Naccepted > 0 {
					o.Stat.Nrejected++
				}
				o.work.reject = true
				last = false

				// new step size
				if o.work.first {
					h = 0.1 * h
				} else {
					h = dxnew
				}

				// last step
				if x+h > xstep {
					h = xstep - x
				}
			}
		}

		// sub-stepping failed
		if failed {
			err = chk.Err("substepping did not converge after %d steps\n", o.Conf.NmaxSS)
			break
		}
	}
	return
}
<|endoftext|>


<commit_before>package telebot

// Option is a shorcut flag type for certain message features
// (so-called options). It means that instead of passing
// fully-fledged SendOptions* to Send(), you can use these
// flags instead.
//
// Supported options are defined as iota-constants.
type Option int

const (
	// NoPreview = SendOptions.DisableWebPagePreview
	NoPreview Option = iota

	// Silent = SendOptions.DisableNotification
	Silent

	// ForceReply = ReplyMarkup.ForceReply
	ForceReply

	// OneTimeKeyboard = ReplyMarkup.OneTimeKeyboard
	OneTimeKeyboard
)

// SendOptions has most complete control over in what way the message
// must be sent, providing an API-complete set of custom properties
// and options.
//
// Despite its power, SendOptions is rather inconvenient to use all
// the way through bot logic, so you might want to consider storing
// and re-using it somewhere or be using Option flags instead.
type SendOptions struct {
	// If the message is a reply, original message.
	ReplyTo *Message

	// See ReplyMarkup struct definition.
	ReplyMarkup *ReplyMarkup

	// For text messages, disables previews for links in this message.
	DisableWebPagePreview bool

	// Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.
	DisableNotification bool

	// ParseMode controls how client apps render your message.
	ParseMode ParseMode
}

func (og *SendOptions) copy() *SendOptions {
	cp := *og
	if cp.ReplyMarkup != nil {
		cp.ReplyMarkup = cp.ReplyMarkup.copy()
	}

	return &cp
}

// ReplyMarkup controls two convenient options for bot-user communications
// such as reply keyboard and inline "keyboard" (a grid of buttons as a part
// of the message).
type ReplyMarkup struct {
	// InlineKeyboard is a grid of InlineButtons displayed in the message.
	//
	// Note: DO NOT confuse with ReplyKeyboard and other keyboard properties!
	InlineKeyboard [][]InlineButton `json:"inline_keyboard,omitempty"`

	// ReplyKeyboard is a grid, consisting of keyboard buttons.
	//
	// Note: you don't need to set HideCustomKeyboard field to show custom keyboard.
	ReplyKeyboard [][]ReplyButton `json:"keyboard,omitempty"`

	// ForceReply forces Telegram clients to display
	// a reply interface to the user (act as if the user
	// has selected the bot‘s message and tapped "Reply").
	ForceReply bool `json:"force_reply,omitempty"`

	// Requests clients to resize the keyboard vertically for optimal fit
	// (e.g. make the keyboard smaller if there are just two rows of buttons).
	//
	// Defaults to false, in which case the custom keyboard is always of the
	// same height as the app's standard keyboard.
	ResizeReplyKeyboard bool `json:"resize_keyboard,omitempty"`

	// Requests clients to hide the reply keyboard as soon as it's been used.
	//
	// Defaults to false.
	OneTimeKeyboard bool `json:"one_time_keyboard,omitempty"`

	// Use this param if you want to force reply from
	// specific users only.
	//
	// Targets:
	// 1) Users that are @mentioned in the text of the Message object;
	// 2) If the bot's message is a reply (has SendOptions.ReplyTo),
	//       sender of the original message.
	Selective bool `json:"selective,omitempty"`
}

func (og *ReplyMarkup) copy() *ReplyMarkup {
	cp := *og

	cp.ReplyKeyboard = make([][]ReplyButton, len(og.ReplyKeyboard))
	for i, row := range og.ReplyKeyboard {
		cp.ReplyKeyboard[i] = make([]ReplyButton, len(row))
		for j, btn := range row {
			cp.ReplyKeyboard[i][j] = btn
		}
	}

	cp.InlineKeyboard = make([][]InlineButton, len(og.InlineKeyboard))
	for i, row := range og.InlineKeyboard {
		cp.InlineKeyboard[i] = make([]InlineButton, len(row))
		for j, btn := range row {
			cp.InlineKeyboard[i][j] = btn
		}
	}

	return &cp
}

// ReplyButton represents a button displayed in reply-keyboard.
//
// Set either Contact or Location to true in order to request
// sensitive info, such as user's phone number or current location.
// (Available in private chats only.)
type ReplyButton struct {
	Text string `json:"text"`

	Contact  bool `json:"request_contact,omitempty"`
	Location bool `json:"request_location,omitempty"`

	Action func(*Callback) `json:"-"`
}

// InlineKeyboardMarkup represents an inline keyboard that appears
// right next to the message it belongs to.
type InlineKeyboardMarkup struct {
	// Array of button rows, each represented by
	// an Array of KeyboardButton objects.
	InlineKeyboard [][]InlineButton `json:"inline_keyboard,omitempty"`
}
<commit_msg>Add ReplyKeyboardRemove<commit_after>package telebot

// Option is a shorcut flag type for certain message features
// (so-called options). It means that instead of passing
// fully-fledged SendOptions* to Send(), you can use these
// flags instead.
//
// Supported options are defined as iota-constants.
type Option int

const (
	// NoPreview = SendOptions.DisableWebPagePreview
	NoPreview Option = iota

	// Silent = SendOptions.DisableNotification
	Silent

	// ForceReply = ReplyMarkup.ForceReply
	ForceReply

	// OneTimeKeyboard = ReplyMarkup.OneTimeKeyboard
	OneTimeKeyboard
)

// SendOptions has most complete control over in what way the message
// must be sent, providing an API-complete set of custom properties
// and options.
//
// Despite its power, SendOptions is rather inconvenient to use all
// the way through bot logic, so you might want to consider storing
// and re-using it somewhere or be using Option flags instead.
type SendOptions struct {
	// If the message is a reply, original message.
	ReplyTo *Message

	// See ReplyMarkup struct definition.
	ReplyMarkup *ReplyMarkup

	// For text messages, disables previews for links in this message.
	DisableWebPagePreview bool

	// Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.
	DisableNotification bool

	// ParseMode controls how client apps render your message.
	ParseMode ParseMode
}

func (og *SendOptions) copy() *SendOptions {
	cp := *og
	if cp.ReplyMarkup != nil {
		cp.ReplyMarkup = cp.ReplyMarkup.copy()
	}

	return &cp
}

// ReplyMarkup controls two convenient options for bot-user communications
// such as reply keyboard and inline "keyboard" (a grid of buttons as a part
// of the message).
type ReplyMarkup struct {
	// InlineKeyboard is a grid of InlineButtons displayed in the message.
	//
	// Note: DO NOT confuse with ReplyKeyboard and other keyboard properties!
	InlineKeyboard [][]InlineButton `json:"inline_keyboard,omitempty"`

	// ReplyKeyboard is a grid, consisting of keyboard buttons.
	//
	// Note: you don't need to set HideCustomKeyboard field to show custom keyboard.
	ReplyKeyboard [][]ReplyButton `json:"keyboard,omitempty"`

	// ForceReply forces Telegram clients to display
	// a reply interface to the user (act as if the user
	// has selected the bot‘s message and tapped "Reply").
	ForceReply bool `json:"force_reply,omitempty"`

	// Requests clients to resize the keyboard vertically for optimal fit
	// (e.g. make the keyboard smaller if there are just two rows of buttons).
	//
	// Defaults to false, in which case the custom keyboard is always of the
	// same height as the app's standard keyboard.
	ResizeReplyKeyboard bool `json:"resize_keyboard,omitempty"`

	// Requests clients to hide the reply keyboard as soon as it's been used.
	//
	// Defaults to false.
	OneTimeKeyboard bool `json:"one_time_keyboard,omitempty"`

	// Requests clients to remove the reply keyboard.
	//
	// Dafaults to false.
	ReplyKeyboardRemove bool `json:"remove_keyboard,omitempty"`

	// Use this param if you want to force reply from
	// specific users only.
	//
	// Targets:
	// 1) Users that are @mentioned in the text of the Message object;
	// 2) If the bot's message is a reply (has SendOptions.ReplyTo),
	//       sender of the original message.
	Selective bool `json:"selective,omitempty"`
}

func (og *ReplyMarkup) copy() *ReplyMarkup {
	cp := *og

	cp.ReplyKeyboard = make([][]ReplyButton, len(og.ReplyKeyboard))
	for i, row := range og.ReplyKeyboard {
		cp.ReplyKeyboard[i] = make([]ReplyButton, len(row))
		for j, btn := range row {
			cp.ReplyKeyboard[i][j] = btn
		}
	}

	cp.InlineKeyboard = make([][]InlineButton, len(og.InlineKeyboard))
	for i, row := range og.InlineKeyboard {
		cp.InlineKeyboard[i] = make([]InlineButton, len(row))
		for j, btn := range row {
			cp.InlineKeyboard[i][j] = btn
		}
	}

	return &cp
}

// ReplyButton represents a button displayed in reply-keyboard.
//
// Set either Contact or Location to true in order to request
// sensitive info, such as user's phone number or current location.
// (Available in private chats only.)
type ReplyButton struct {
	Text string `json:"text"`

	Contact  bool `json:"request_contact,omitempty"`
	Location bool `json:"request_location,omitempty"`

	Action func(*Callback) `json:"-"`
}

// InlineKeyboardMarkup represents an inline keyboard that appears
// right next to the message it belongs to.
type InlineKeyboardMarkup struct {
	// Array of button rows, each represented by
	// an Array of KeyboardButton objects.
	InlineKeyboard [][]InlineButton `json:"inline_keyboard,omitempty"`
}
<|endoftext|>


<commit_before>// Copyright 2014 <chaishushan{AT}gmail.com>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package tiff

type Options struct {
	//
}
<commit_msg>more Options fields<commit_after>// Copyright 2014 <chaishushan{AT}gmail.com>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package tiff

type Options struct {
	Compression CompressionType
	Predictor   bool
	EntryMap    map[TagType]*IFDEntry
}
<|endoftext|>


<commit_before>package pg

import (
	"crypto/tls"
	"net"
	"time"

	"gopkg.in/pg.v5/internal/pool"
)

// Database connection options.
type Options struct {
	// Network type, either tcp or unix.
	// Default is tcp.
	Network string
	// TCP host:port or Unix socket depending on Network.
	Addr     string
	User     string
	Password string
	Database string

	// TLS config for secure connections.
	TLSConfig *tls.Config

	// Maximum number of retries before giving up.
	// Default is to not retry failed queries.
	MaxRetries int
	// Whether to retry queries cancelled because of statement_timeout.
	RetryStatementTimeout bool

	// Dial timeout for establishing new connections.
	// Default is 5 seconds.
	DialTimeout time.Duration
	// Timeout for socket reads. If reached, commands will fail
	// with a timeout instead of blocking.
	ReadTimeout time.Duration
	// Timeout for socket writes. If reached, commands will fail
	// with a timeout instead of blocking.
	WriteTimeout time.Duration

	// Maximum number of socket connections.
	// Default is 20 connections.
	PoolSize int
	// Amount of time client waits for free connection if all
	// connections are busy before returning an error.
	// Default is 5 seconds.
	PoolTimeout time.Duration
	// Amount of time after which client closes idle connections.
	// Default is to not close idle connections.
	IdleTimeout time.Duration
	// Frequency of idle checks.
	// Default is 1 minute.
	IdleCheckFrequency time.Duration
}

func (opt *Options) init() {
	if opt.Network == "" {
		opt.Network = "tcp"
	}

	if opt.Addr == "" {
		switch opt.Network {
		case "tcp":
			opt.Addr = "localhost:5432"
		case "unix":
			opt.Addr = "/var/run/postgresql/.s.PGSQL.5432"
		}
	}

	if opt.PoolSize == 0 {
		opt.PoolSize = 20
	}

	if opt.PoolTimeout == 0 {
		if opt.ReadTimeout != 0 {
			opt.PoolTimeout = opt.ReadTimeout + time.Second
		} else {
			opt.PoolTimeout = 30 * time.Second
		}
	}

	if opt.DialTimeout == 0 {
		opt.DialTimeout = 5 * time.Second
	}

	if opt.IdleCheckFrequency == 0 {
		opt.IdleCheckFrequency = time.Minute
	}
}

func (opt *Options) getDialer() func() (net.Conn, error) {
	return func() (net.Conn, error) {
		return net.DialTimeout(opt.Network, opt.Addr, opt.DialTimeout)
	}
}

func newConnPool(opt *Options) *pool.ConnPool {
	p := pool.NewConnPool(
		opt.getDialer(),
		opt.PoolSize,
		opt.PoolTimeout,
		opt.IdleTimeout,
		opt.IdleCheckFrequency,
	)
	p.OnClose = func(cn *pool.Conn) error {
		return terminateConn(cn)
	}
	return p
}
<commit_msg>Support Dialer.<commit_after>package pg

import (
	"crypto/tls"
	"net"
	"time"

	"gopkg.in/pg.v5/internal/pool"
)

// Database connection options.
type Options struct {
	// Network type, either tcp or unix.
	// Default is tcp.
	Network string
	// TCP host:port or Unix socket depending on Network.
	Addr string

	// Dialer creates new network connection and has priority over
	// Network and Addr options.
	Dialer func(network, addr string) (net.Conn, error)

	User     string
	Password string
	Database string

	// TLS config for secure connections.
	TLSConfig *tls.Config

	// Maximum number of retries before giving up.
	// Default is to not retry failed queries.
	MaxRetries int
	// Whether to retry queries cancelled because of statement_timeout.
	RetryStatementTimeout bool

	// Dial timeout for establishing new connections.
	// Default is 5 seconds.
	DialTimeout time.Duration
	// Timeout for socket reads. If reached, commands will fail
	// with a timeout instead of blocking.
	ReadTimeout time.Duration
	// Timeout for socket writes. If reached, commands will fail
	// with a timeout instead of blocking.
	WriteTimeout time.Duration

	// Maximum number of socket connections.
	// Default is 20 connections.
	PoolSize int
	// Amount of time client waits for free connection if all
	// connections are busy before returning an error.
	// Default is 5 seconds.
	PoolTimeout time.Duration
	// Amount of time after which client closes idle connections.
	// Default is to not close idle connections.
	IdleTimeout time.Duration
	// Frequency of idle checks.
	// Default is 1 minute.
	IdleCheckFrequency time.Duration
}

func (opt *Options) init() {
	if opt.Network == "" {
		opt.Network = "tcp"
	}

	if opt.Addr == "" {
		switch opt.Network {
		case "tcp":
			opt.Addr = "localhost:5432"
		case "unix":
			opt.Addr = "/var/run/postgresql/.s.PGSQL.5432"
		}
	}

	if opt.PoolSize == 0 {
		opt.PoolSize = 20
	}

	if opt.PoolTimeout == 0 {
		if opt.ReadTimeout != 0 {
			opt.PoolTimeout = opt.ReadTimeout + time.Second
		} else {
			opt.PoolTimeout = 30 * time.Second
		}
	}

	if opt.DialTimeout == 0 {
		opt.DialTimeout = 5 * time.Second
	}

	if opt.IdleCheckFrequency == 0 {
		opt.IdleCheckFrequency = time.Minute
	}
}

func (opt *Options) getDialer() func() (net.Conn, error) {
	if opt.Dialer != nil {
		return func() (net.Conn, error) {
			return opt.Dialer(opt.Network, opt.Addr)
		}
	}
	return func() (net.Conn, error) {
		return net.DialTimeout(opt.Network, opt.Addr, opt.DialTimeout)
	}
}

func newConnPool(opt *Options) *pool.ConnPool {
	p := pool.NewConnPool(
		opt.getDialer(),
		opt.PoolSize,
		opt.PoolTimeout,
		opt.IdleTimeout,
		opt.IdleCheckFrequency,
	)
	p.OnClose = func(cn *pool.Conn) error {
		return terminateConn(cn)
	}
	return p
}
<|endoftext|>


<commit_before>package alloc

import (
	"time"
)

// Buffer is a recyclable allocation of a byte array. Buffer.Release() recycles
// the buffer into an internal buffer pool, in order to recreate a buffer more
// quickly.
type Buffer struct {
	head  []byte
	pool  *bufferPool
	Value []byte
}

// Release recycles the buffer into an internal buffer pool.
func (b *Buffer) Release() {
	b.pool.free(b)
	b.head = nil
	b.Value = nil
	b.pool = nil
}

// Clear clears the content of the buffer, results an empty buffer with
// Len() = 0.
func (b *Buffer) Clear() *Buffer {
	b.Value = b.head[:0]
	return b
}

// AppendBytes appends one or more bytes to the end of the buffer.
func (b *Buffer) AppendBytes(bytes ...byte) *Buffer {
	b.Value = append(b.Value, bytes...)
	return b
}

// Append appends a byte array to the end of the buffer.
func (b *Buffer) Append(data []byte) *Buffer {
	b.Value = append(b.Value, data...)
	return b
}

func (b *Buffer) Bytes() []byte {
	return b.Value
}

// Slice cuts the buffer at the given position.
func (b *Buffer) Slice(from, to int) *Buffer {
	b.Value = b.Value[from:to]
	return b
}

// SliceFrom cuts the buffer at the given position.
func (b *Buffer) SliceFrom(from int) *Buffer {
	b.Value = b.Value[from:]
	return b
}

// Len returns the length of the buffer content.
func (b *Buffer) Len() int {
	return len(b.Value)
}

// IsFull returns true if the buffer has no more room to grow.
func (b *Buffer) IsFull() bool {
	return len(b.Value) == cap(b.Value)
}

// Write implements Write method in io.Writer.
func (b *Buffer) Write(data []byte) (int, error) {
	b.Append(data)
	return len(data), nil
}

type bufferPool struct {
	chain        chan []byte
	bufferSize   int
	buffers2Keep int
}

func newBufferPool(bufferSize, buffers2Keep, poolSize int) *bufferPool {
	pool := &bufferPool{
		chain:        make(chan []byte, poolSize),
		bufferSize:   bufferSize,
		buffers2Keep: buffers2Keep,
	}
	for i := 0; i < buffers2Keep; i++ {
		pool.chain <- make([]byte, bufferSize)
	}
	go pool.cleanup(time.Tick(1 * time.Second))
	return pool
}

func (p *bufferPool) allocate() *Buffer {
	var b []byte
	select {
	case b = <-p.chain:
	default:
		b = make([]byte, p.bufferSize)
	}
	return &Buffer{
		head:  b,
		pool:  p,
		Value: b,
	}
}

func (p *bufferPool) free(buffer *Buffer) {
	select {
	case p.chain <- buffer.head:
	default:
	}
}

func (p *bufferPool) cleanup(tick <-chan time.Time) {
	for range tick {
		pSize := len(p.chain)
		if pSize > p.buffers2Keep {
			<-p.chain
			continue
		}
		for delta := p.buffers2Keep - pSize; delta > 0; delta-- {
			select {
			case p.chain <- make([]byte, p.bufferSize):
			default:
				break
			}
		}
	}
}

var smallPool = newBufferPool(1024, 64, 512)
var mediumPool = newBufferPool(8*1024, 256, 2048)
var largePool = newBufferPool(64*1024, 128, 1024)

// NewSmallBuffer creates a Buffer with 1K bytes of arbitrary content.
func NewSmallBuffer() *Buffer {
	return smallPool.allocate()
}

// NewBuffer creates a Buffer with 8K bytes of arbitrary content.
func NewBuffer() *Buffer {
	return mediumPool.allocate()
}

// NewLargeBuffer creates a Buffer with 64K bytes of arbitrary content.
func NewLargeBuffer() *Buffer {
	return largePool.allocate()
}
<commit_msg>remove unnecessary cleanup routine<commit_after>package alloc

// Buffer is a recyclable allocation of a byte array. Buffer.Release() recycles
// the buffer into an internal buffer pool, in order to recreate a buffer more
// quickly.
type Buffer struct {
	head  []byte
	pool  *bufferPool
	Value []byte
}

// Release recycles the buffer into an internal buffer pool.
func (b *Buffer) Release() {
	b.pool.free(b)
	b.head = nil
	b.Value = nil
	b.pool = nil
}

// Clear clears the content of the buffer, results an empty buffer with
// Len() = 0.
func (b *Buffer) Clear() *Buffer {
	b.Value = b.head[:0]
	return b
}

// AppendBytes appends one or more bytes to the end of the buffer.
func (b *Buffer) AppendBytes(bytes ...byte) *Buffer {
	b.Value = append(b.Value, bytes...)
	return b
}

// Append appends a byte array to the end of the buffer.
func (b *Buffer) Append(data []byte) *Buffer {
	b.Value = append(b.Value, data...)
	return b
}

func (b *Buffer) Bytes() []byte {
	return b.Value
}

// Slice cuts the buffer at the given position.
func (b *Buffer) Slice(from, to int) *Buffer {
	b.Value = b.Value[from:to]
	return b
}

// SliceFrom cuts the buffer at the given position.
func (b *Buffer) SliceFrom(from int) *Buffer {
	b.Value = b.Value[from:]
	return b
}

// Len returns the length of the buffer content.
func (b *Buffer) Len() int {
	return len(b.Value)
}

// IsFull returns true if the buffer has no more room to grow.
func (b *Buffer) IsFull() bool {
	return len(b.Value) == cap(b.Value)
}

// Write implements Write method in io.Writer.
func (b *Buffer) Write(data []byte) (int, error) {
	b.Append(data)
	return len(data), nil
}

type bufferPool struct {
	chain        chan []byte
	bufferSize   int
	buffers2Keep int
}

func newBufferPool(bufferSize, poolSize int) *bufferPool {
	pool := &bufferPool{
		chain:      make(chan []byte, poolSize),
		bufferSize: bufferSize,
	}
	for i := 0; i < poolSize; i++ {
		pool.chain <- make([]byte, bufferSize)
	}
	return pool
}

func (p *bufferPool) allocate() *Buffer {
	var b []byte
	select {
	case b = <-p.chain:
	default:
		b = make([]byte, p.bufferSize)
	}
	return &Buffer{
		head:  b,
		pool:  p,
		Value: b,
	}
}

func (p *bufferPool) free(buffer *Buffer) {
	select {
	case p.chain <- buffer.head:
	default:
	}
}

var smallPool = newBufferPool(1024, 256)
var mediumPool = newBufferPool(8*1024, 512)
var largePool = newBufferPool(64*1024, 128)

// NewSmallBuffer creates a Buffer with 1K bytes of arbitrary content.
func NewSmallBuffer() *Buffer {
	return smallPool.allocate()
}

// NewBuffer creates a Buffer with 8K bytes of arbitrary content.
func NewBuffer() *Buffer {
	return mediumPool.allocate()
}

// NewLargeBuffer creates a Buffer with 64K bytes of arbitrary content.
func NewLargeBuffer() *Buffer {
	return largePool.allocate()
}
<|endoftext|>


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

package serial // import "go.bug.st/serial.v1"

/*

// MSDN article on Serial Communications:
// http://msdn.microsoft.com/en-us/library/ff802693.aspx

// Arduino Playground article on serial communication with Windows API:
// http://playground.arduino.cc/Interfacing/CPPWindows

*/

import "syscall"

type windowsPort struct {
	handle syscall.Handle
}

//go:generate go run extras/mksyscall_windows.go -output syscall_windows.go serial_windows.go

//sys regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, value *uint16, valueLen *uint32) (regerrno error) = advapi32.RegEnumValueW

func nativeGetPortsList() ([]string, error) {
	subKey, err := syscall.UTF16PtrFromString("HARDWARE\\DEVICEMAP\\SERIALCOMM\\")
	if err != nil {
		return nil, &PortError{code: ErrorEnumeratingPorts}
	}

	var h syscall.Handle
	if syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, subKey, 0, syscall.KEY_READ, &h) != nil {
		return nil, &PortError{code: ErrorEnumeratingPorts}
	}
	defer syscall.RegCloseKey(h)

	var valuesCount uint32
	if syscall.RegQueryInfoKey(h, nil, nil, nil, nil, nil, nil, &valuesCount, nil, nil, nil, nil) != nil {
		return nil, &PortError{code: ErrorEnumeratingPorts}
	}

	list := make([]string, valuesCount)
	for i := range list {
		var data [1024]uint16
		dataSize := uint32(len(data))
		var name [1024]uint16
		nameSize := uint32(len(name))
		if regEnumValue(h, uint32(i), &name[0], &nameSize, nil, nil, &data[0], &dataSize) != nil {
			return nil, &PortError{code: ErrorEnumeratingPorts}
		}
		list[i] = syscall.UTF16ToString(data[:])
	}
	return list, nil
}

func (port *windowsPort) Close() error {
	return syscall.CloseHandle(port.handle)
}

func (port *windowsPort) Read(p []byte) (int, error) {
	var readed uint32
	params := &dcb{}
	for {
		if err := syscall.ReadFile(port.handle, p, &readed, nil); err != nil {
			return int(readed), err
		}
		if readed > 0 {
			return int(readed), nil
		}

		// At the moment it seems that the only reliable way to check if
		// a serial port is alive in Windows is to check if the SetCommState
		// function fails.

		getCommState(port.handle, params)
		if err := setCommState(port.handle, params); err != nil {
			port.Close()
			return 0, err
		}
	}
}

func (port *windowsPort) Write(p []byte) (int, error) {
	var writed uint32
	err := syscall.WriteFile(port.handle, p, &writed, nil)
	return int(writed), err
}

const (
	dcbBinary                = 0x00000001
	dcbParity                = 0x00000002
	dcbOutXCTSFlow           = 0x00000004
	dcbOutXDSRFlow           = 0x00000008
	dcbDTRControlDisableMask = ^0x00000030
	dcbDTRControlEnable      = 0x00000010
	dcbDTRControlHandshake   = 0x00000020
	dcbDSRSensitivity        = 0x00000040
	dcbTXContinueOnXOFF      = 0x00000080
	dcbOutX                  = 0x00000100
	dcbInX                   = 0x00000200
	dcbErrorChar             = 0x00000400
	dcbNull                  = 0x00000800
	dcbRTSControlDisbaleMask = ^0x00003000
	dcbRTSControlEnable      = 0x00001000
	dcbRTSControlHandshake   = 0x00002000
	dcbRTSControlToggle      = 0x00003000
	dcbAbortOnError          = 0x00004000
)

type dcb struct {
	DCBlength uint32
	BaudRate  uint32

	// Flags field is a bitfield
	//  fBinary            :1
	//  fParity            :1
	//  fOutxCtsFlow       :1
	//  fOutxDsrFlow       :1
	//  fDtrControl        :2
	//  fDsrSensitivity    :1
	//  fTXContinueOnXoff  :1
	//  fOutX              :1
	//  fInX               :1
	//  fErrorChar         :1
	//  fNull              :1
	//  fRtsControl        :2
	//  fAbortOnError      :1
	//  fDummy2            :17
	Flags uint32

	wReserved  uint16
	XonLim     uint16
	XoffLim    uint16
	ByteSize   byte
	Parity     byte
	StopBits   byte
	XonChar    byte
	XoffChar   byte
	ErrorChar  byte
	EOFChar    byte
	EvtChar    byte
	wReserved1 uint16
}

type commTimeouts struct {
	ReadIntervalTimeout         uint32
	ReadTotalTimeoutMultiplier  uint32
	ReadTotalTimeoutConstant    uint32
	WriteTotalTimeoutMultiplier uint32
	WriteTotalTimeoutConstant   uint32
}

//sys getCommState(handle syscall.Handle, dcb *dcb) (err error) = GetCommState
//sys setCommState(handle syscall.Handle, dcb *dcb) (err error) = SetCommState
//sys setCommTimeouts(handle syscall.Handle, timeouts *commTimeouts) (err error) = SetCommTimeouts

const (
	noParity    = 0
	oddParity   = 1
	evenParity  = 2
	markParity  = 3
	spaceParity = 4
)

var parityMap = map[Parity]byte{
	NoParity:    noParity,
	OddParity:   oddParity,
	EvenParity:  evenParity,
	MarkParity:  markParity,
	SpaceParity: spaceParity,
}

const (
	oneStopBit   = 0
	one5StopBits = 1
	twoStopBits  = 2
)

var stopBitsMap = map[StopBits]byte{
	OneStopBit:           oneStopBit,
	OnePointFiveStopBits: one5StopBits,
	TwoStopBits:          twoStopBits,
}

func (port *windowsPort) SetMode(mode *Mode) error {
	params := dcb{}
	if getCommState(port.handle, &params) != nil {
		port.Close()
		return &PortError{code: InvalidSerialPort}
	}
	if mode.BaudRate == 0 {
		params.BaudRate = 9600 // Default to 9600
	} else {
		params.BaudRate = uint32(mode.BaudRate)
	}
	if mode.DataBits == 0 {
		params.ByteSize = 8 // Default to 8 bits
	} else {
		params.ByteSize = byte(mode.DataBits)
	}
	params.StopBits = stopBitsMap[mode.StopBits]
	params.Parity = parityMap[mode.Parity]
	if setCommState(port.handle, &params) != nil {
		port.Close()
		return &PortError{code: InvalidSerialPort}
	}
	return nil
}

func nativeOpen(portName string, mode *Mode) (*windowsPort, error) {
	portName = "\\\\.\\" + portName
	path, err := syscall.UTF16PtrFromString(portName)
	if err != nil {
		return nil, err
	}
	handle, err := syscall.CreateFile(
		path,
		syscall.GENERIC_READ|syscall.GENERIC_WRITE,
		0, nil,
		syscall.OPEN_EXISTING,
		0, //syscall.FILE_FLAG_OVERLAPPED,
		0)
	if err != nil {
		switch err {
		case syscall.ERROR_ACCESS_DENIED:
			return nil, &PortError{code: PortBusy}
		case syscall.ERROR_FILE_NOT_FOUND:
			return nil, &PortError{code: PortNotFound}
		}
		return nil, err
	}
	// Create the serial port
	port := &windowsPort{
		handle: handle,
	}

	// Set port parameters
	if port.SetMode(mode) != nil {
		port.Close()
		return nil, &PortError{code: InvalidSerialPort}
	}

	params := &dcb{}
	if getCommState(port.handle, params) != nil {
		port.Close()
		return nil, &PortError{code: InvalidSerialPort}
	}
	params.Flags |= dcbRTSControlEnable | dcbDTRControlEnable
	params.Flags &= ^uint32(dcbOutXCTSFlow)
	params.Flags &= ^uint32(dcbOutXDSRFlow)
	params.Flags &= ^uint32(dcbDSRSensitivity)
	params.Flags |= dcbTXContinueOnXOFF
	params.Flags &= ^uint32(dcbInX | dcbOutX)
	params.Flags &= ^uint32(dcbErrorChar)
	params.Flags &= ^uint32(dcbNull)
	params.Flags &= ^uint32(dcbAbortOnError)
	params.XonLim = 2048
	params.XoffLim = 512
	params.XonChar = 17  // DC1
	params.XoffChar = 19 // C3
	if setCommState(port.handle, params) != nil {
		port.Close()
		return nil, &PortError{code: InvalidSerialPort}
	}

	// Set timeouts to 1 second
	timeouts := &commTimeouts{
		ReadIntervalTimeout:         0xFFFFFFFF,
		ReadTotalTimeoutMultiplier:  0xFFFFFFFF,
		ReadTotalTimeoutConstant:    1000, // 1 sec
		WriteTotalTimeoutConstant:   0,
		WriteTotalTimeoutMultiplier: 0,
	}
	if setCommTimeouts(port.handle, timeouts) != nil {
		port.Close()
		return nil, &PortError{code: InvalidSerialPort}
	}

	return port, nil
}
<commit_msg>Slighlty improved bits handling in windows<commit_after>//
// Copyright 2014-2016 Cristian Maglie. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//

package serial // import "go.bug.st/serial.v1"

/*

// MSDN article on Serial Communications:
// http://msdn.microsoft.com/en-us/library/ff802693.aspx

// Arduino Playground article on serial communication with Windows API:
// http://playground.arduino.cc/Interfacing/CPPWindows

*/

import "syscall"

type windowsPort struct {
	handle syscall.Handle
}

//go:generate go run extras/mksyscall_windows.go -output syscall_windows.go serial_windows.go

//sys regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, value *uint16, valueLen *uint32) (regerrno error) = advapi32.RegEnumValueW

func nativeGetPortsList() ([]string, error) {
	subKey, err := syscall.UTF16PtrFromString("HARDWARE\\DEVICEMAP\\SERIALCOMM\\")
	if err != nil {
		return nil, &PortError{code: ErrorEnumeratingPorts}
	}

	var h syscall.Handle
	if syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, subKey, 0, syscall.KEY_READ, &h) != nil {
		return nil, &PortError{code: ErrorEnumeratingPorts}
	}
	defer syscall.RegCloseKey(h)

	var valuesCount uint32
	if syscall.RegQueryInfoKey(h, nil, nil, nil, nil, nil, nil, &valuesCount, nil, nil, nil, nil) != nil {
		return nil, &PortError{code: ErrorEnumeratingPorts}
	}

	list := make([]string, valuesCount)
	for i := range list {
		var data [1024]uint16
		dataSize := uint32(len(data))
		var name [1024]uint16
		nameSize := uint32(len(name))
		if regEnumValue(h, uint32(i), &name[0], &nameSize, nil, nil, &data[0], &dataSize) != nil {
			return nil, &PortError{code: ErrorEnumeratingPorts}
		}
		list[i] = syscall.UTF16ToString(data[:])
	}
	return list, nil
}

func (port *windowsPort) Close() error {
	return syscall.CloseHandle(port.handle)
}

func (port *windowsPort) Read(p []byte) (int, error) {
	var readed uint32
	params := &dcb{}
	for {
		if err := syscall.ReadFile(port.handle, p, &readed, nil); err != nil {
			return int(readed), err
		}
		if readed > 0 {
			return int(readed), nil
		}

		// At the moment it seems that the only reliable way to check if
		// a serial port is alive in Windows is to check if the SetCommState
		// function fails.

		getCommState(port.handle, params)
		if err := setCommState(port.handle, params); err != nil {
			port.Close()
			return 0, err
		}
	}
}

func (port *windowsPort) Write(p []byte) (int, error) {
	var writed uint32
	err := syscall.WriteFile(port.handle, p, &writed, nil)
	return int(writed), err
}

const (
	dcbBinary                uint32 = 0x00000001
	dcbParity                       = 0x00000002
	dcbOutXCTSFlow                  = 0x00000004
	dcbOutXDSRFlow                  = 0x00000008
	dcbDTRControlDisableMask        = ^uint32(0x00000030)
	dcbDTRControlEnable             = 0x00000010
	dcbDTRControlHandshake          = 0x00000020
	dcbDSRSensitivity               = 0x00000040
	dcbTXContinueOnXOFF             = 0x00000080
	dcbOutX                         = 0x00000100
	dcbInX                          = 0x00000200
	dcbErrorChar                    = 0x00000400
	dcbNull                         = 0x00000800
	dcbRTSControlDisbaleMask        = ^uint32(0x00003000)
	dcbRTSControlEnable             = 0x00001000
	dcbRTSControlHandshake          = 0x00002000
	dcbRTSControlToggle             = 0x00003000
	dcbAbortOnError                 = 0x00004000
)

type dcb struct {
	DCBlength uint32
	BaudRate  uint32

	// Flags field is a bitfield
	//  fBinary            :1
	//  fParity            :1
	//  fOutxCtsFlow       :1
	//  fOutxDsrFlow       :1
	//  fDtrControl        :2
	//  fDsrSensitivity    :1
	//  fTXContinueOnXoff  :1
	//  fOutX              :1
	//  fInX               :1
	//  fErrorChar         :1
	//  fNull              :1
	//  fRtsControl        :2
	//  fAbortOnError      :1
	//  fDummy2            :17
	Flags uint32

	wReserved  uint16
	XonLim     uint16
	XoffLim    uint16
	ByteSize   byte
	Parity     byte
	StopBits   byte
	XonChar    byte
	XoffChar   byte
	ErrorChar  byte
	EOFChar    byte
	EvtChar    byte
	wReserved1 uint16
}

type commTimeouts struct {
	ReadIntervalTimeout         uint32
	ReadTotalTimeoutMultiplier  uint32
	ReadTotalTimeoutConstant    uint32
	WriteTotalTimeoutMultiplier uint32
	WriteTotalTimeoutConstant   uint32
}

//sys getCommState(handle syscall.Handle, dcb *dcb) (err error) = GetCommState
//sys setCommState(handle syscall.Handle, dcb *dcb) (err error) = SetCommState
//sys setCommTimeouts(handle syscall.Handle, timeouts *commTimeouts) (err error) = SetCommTimeouts

const (
	noParity    = 0
	oddParity   = 1
	evenParity  = 2
	markParity  = 3
	spaceParity = 4
)

var parityMap = map[Parity]byte{
	NoParity:    noParity,
	OddParity:   oddParity,
	EvenParity:  evenParity,
	MarkParity:  markParity,
	SpaceParity: spaceParity,
}

const (
	oneStopBit   = 0
	one5StopBits = 1
	twoStopBits  = 2
)

var stopBitsMap = map[StopBits]byte{
	OneStopBit:           oneStopBit,
	OnePointFiveStopBits: one5StopBits,
	TwoStopBits:          twoStopBits,
}

func (port *windowsPort) SetMode(mode *Mode) error {
	params := dcb{}
	if getCommState(port.handle, &params) != nil {
		port.Close()
		return &PortError{code: InvalidSerialPort}
	}
	if mode.BaudRate == 0 {
		params.BaudRate = 9600 // Default to 9600
	} else {
		params.BaudRate = uint32(mode.BaudRate)
	}
	if mode.DataBits == 0 {
		params.ByteSize = 8 // Default to 8 bits
	} else {
		params.ByteSize = byte(mode.DataBits)
	}
	params.StopBits = stopBitsMap[mode.StopBits]
	params.Parity = parityMap[mode.Parity]
	if setCommState(port.handle, &params) != nil {
		port.Close()
		return &PortError{code: InvalidSerialPort}
	}
	return nil
}

func nativeOpen(portName string, mode *Mode) (*windowsPort, error) {
	portName = "\\\\.\\" + portName
	path, err := syscall.UTF16PtrFromString(portName)
	if err != nil {
		return nil, err
	}
	handle, err := syscall.CreateFile(
		path,
		syscall.GENERIC_READ|syscall.GENERIC_WRITE,
		0, nil,
		syscall.OPEN_EXISTING,
		0, //syscall.FILE_FLAG_OVERLAPPED,
		0)
	if err != nil {
		switch err {
		case syscall.ERROR_ACCESS_DENIED:
			return nil, &PortError{code: PortBusy}
		case syscall.ERROR_FILE_NOT_FOUND:
			return nil, &PortError{code: PortNotFound}
		}
		return nil, err
	}
	// Create the serial port
	port := &windowsPort{
		handle: handle,
	}

	// Set port parameters
	if port.SetMode(mode) != nil {
		port.Close()
		return nil, &PortError{code: InvalidSerialPort}
	}

	params := &dcb{}
	if getCommState(port.handle, params) != nil {
		port.Close()
		return nil, &PortError{code: InvalidSerialPort}
	}
	params.Flags &= dcbRTSControlDisbaleMask
	params.Flags |= dcbRTSControlEnable
	params.Flags &= dcbDTRControlDisableMask
	params.Flags |= dcbDTRControlEnable
	params.Flags &^= dcbOutXCTSFlow
	params.Flags &^= dcbOutXDSRFlow
	params.Flags &^= dcbDSRSensitivity
	params.Flags |= dcbTXContinueOnXOFF
	params.Flags &^= dcbInX
	params.Flags &^= dcbOutX
	params.Flags &^= dcbErrorChar
	params.Flags &^= dcbNull
	params.Flags &^= dcbAbortOnError
	params.XonLim = 2048
	params.XoffLim = 512
	params.XonChar = 17  // DC1
	params.XoffChar = 19 // C3
	if setCommState(port.handle, params) != nil {
		port.Close()
		return nil, &PortError{code: InvalidSerialPort}
	}

	// Set timeouts to 1 second
	timeouts := &commTimeouts{
		ReadIntervalTimeout:         0xFFFFFFFF,
		ReadTotalTimeoutMultiplier:  0xFFFFFFFF,
		ReadTotalTimeoutConstant:    1000, // 1 sec
		WriteTotalTimeoutConstant:   0,
		WriteTotalTimeoutMultiplier: 0,
	}
	if setCommTimeouts(port.handle, timeouts) != nil {
		port.Close()
		return nil, &PortError{code: InvalidSerialPort}
	}

	return port, nil
}
<|endoftext|>


<commit_before>package queue

import (
	//"runtime"
	"runtime"
	"sync"
	"sync/atomic"
	"time"
	"unsafe"

	"github.com/stephane-martin/skewer/model"
	"github.com/stephane-martin/skewer/utils"
)

type messageNode struct {
	next *messageNode
	msg  *model.FullMessage
}

type MessageQueue struct {
	head     *messageNode
	tail     *messageNode
	disposed int32
	pool     *sync.Pool
}

func NewMessageQueue() *MessageQueue {
	stub := &messageNode{}
	return &MessageQueue{head: stub, tail: stub, disposed: 0, pool: &sync.Pool{New: func() interface{} {
		return &messageNode{}
	}}}
}

func (q *MessageQueue) Disposed() bool {
	return atomic.LoadInt32(&q.disposed) == 1
}

func (q *MessageQueue) Dispose() {
	atomic.StoreInt32(&q.disposed, 1)
}

func (q *MessageQueue) Has() bool {
	return q.tail.next != nil
}

func (q *MessageQueue) Wait(timeout time.Duration) bool {
	var start time.Time
	if timeout > 0 {
		start = time.Now()
	}
	var nb uint64
	for {
		if q.tail.next != nil {
			return true
		}
		if timeout > 0 && time.Since(start) >= timeout {
			return false
		}
		if atomic.LoadInt32(&q.disposed) == 1 {
			return false
		}
		if nb < 22 {
			runtime.Gosched()
		} else if nb < 24 {
			time.Sleep(1000000)
		} else if nb < 26 {
			time.Sleep(10000000)
		} else {
			time.Sleep(100000000)
		}
		nb++
	}
}

func (q *MessageQueue) Get() (*model.FullMessage, error) {
	tail := q.tail
	next := tail.next
	if next != nil {
		//q.tail = next
		//tail.msg = next.msg
		//m = tail.msg
		(*messageNode)(atomic.SwapPointer((*unsafe.Pointer)(unsafe.Pointer(&q.tail)), unsafe.Pointer(next))).msg = next.msg
		q.pool.Put(tail)
		return next.msg, nil
	} else if q.Disposed() {
		return nil, utils.ErrDisposed
	} else {
		return nil, nil
	}
}

func (q *MessageQueue) Put(m model.FullMessage) error {
	if q.Disposed() {
		return utils.ErrDisposed
	}
	n := q.pool.Get().(*messageNode)
	n.msg = &m
	n.next = nil
	(*messageNode)(atomic.SwapPointer((*unsafe.Pointer)(unsafe.Pointer(&q.head)), unsafe.Pointer(n))).next = n
	// q.head.next = n
	// q.head = n
	return nil
}

func (q *MessageQueue) GetMany(max int) []*model.FullMessage {
	var elt *model.FullMessage
	var err error
	res := make([]*model.FullMessage, 0, max)
	for {
		elt, err = q.Get()
		if elt == nil || err != nil {
			break
		}
		res = append(res, elt)
		if len(res) == max {
			break
		}
	}
	return res
}
<commit_msg>formatting<commit_after>package queue

import (
	//"runtime"
	"runtime"
	"sync"
	"sync/atomic"
	"time"
	"unsafe"

	"github.com/stephane-martin/skewer/model"
	"github.com/stephane-martin/skewer/utils"
)

type messageNode struct {
	next *messageNode
	msg  *model.FullMessage
}

type MessageQueue struct {
	head     *messageNode
	tail     *messageNode
	disposed int32
	pool     *sync.Pool
}

func NewMessageQueue() *MessageQueue {
	stub := &messageNode{}
	return &MessageQueue{
		disposed: 0,
		head:     stub,
		tail:     stub,
		pool: &sync.Pool{
			New: func() interface{} {
				return &messageNode{}
			},
		},
	}
}

func (q *MessageQueue) Disposed() bool {
	return atomic.LoadInt32(&q.disposed) == 1
}

func (q *MessageQueue) Dispose() {
	atomic.StoreInt32(&q.disposed, 1)
}

func (q *MessageQueue) Has() bool {
	return q.tail.next != nil
}

func (q *MessageQueue) Wait(timeout time.Duration) bool {
	var start time.Time
	if timeout > 0 {
		start = time.Now()
	}
	var nb uint64
	for {
		if q.tail.next != nil {
			return true
		}
		if timeout > 0 && time.Since(start) >= timeout {
			return false
		}
		if atomic.LoadInt32(&q.disposed) == 1 {
			return false
		}
		if nb < 22 {
			runtime.Gosched()
		} else if nb < 24 {
			time.Sleep(1000000)
		} else if nb < 26 {
			time.Sleep(10000000)
		} else {
			time.Sleep(100000000)
		}
		nb++
	}
}

func (q *MessageQueue) Get() (*model.FullMessage, error) {
	tail := q.tail
	next := tail.next
	if next != nil {
		//q.tail = next
		//tail.msg = next.msg
		//m = tail.msg
		(*messageNode)(atomic.SwapPointer((*unsafe.Pointer)(unsafe.Pointer(&q.tail)), unsafe.Pointer(next))).msg = next.msg
		q.pool.Put(tail)
		return next.msg, nil
	} else if q.Disposed() {
		return nil, utils.ErrDisposed
	} else {
		return nil, nil
	}
}

func (q *MessageQueue) Put(m model.FullMessage) error {
	if q.Disposed() {
		return utils.ErrDisposed
	}
	n := q.pool.Get().(*messageNode)
	n.msg = &m
	n.next = nil
	(*messageNode)(atomic.SwapPointer((*unsafe.Pointer)(unsafe.Pointer(&q.head)), unsafe.Pointer(n))).next = n
	// q.head.next = n
	// q.head = n
	return nil
}

func (q *MessageQueue) GetMany(max int) []*model.FullMessage {
	var elt *model.FullMessage
	var err error
	res := make([]*model.FullMessage, 0, max)
	for {
		elt, err = q.Get()
		if elt == nil || err != nil {
			break
		}
		res = append(res, elt)
		if len(res) == max {
			break
		}
	}
	return res
}
<|endoftext|>


<commit_before>// Copyright (c) 2013 Erik St. Martin, Brian Ketelsen. All rights reserved.
// Use of this source code is governed by The MIT License (MIT) that can be
// found in the LICENSE file.

package server

import (
	"github.com/goraft/raft"
	"github.com/skynetservices/skydns/msg"
	"github.com/skynetservices/skydns/registry"
	"log"
	"time"
)

// Command for adding service to registry
type AddServiceCommand struct {
	Service msg.Service
}

// Creates a new AddServiceCommand
func NewAddServiceCommand(s msg.Service) *AddServiceCommand {
	s.Expires = getExpirationTime(s.TTL)

	return &AddServiceCommand{s}
}

// Name of command
func (c *AddServiceCommand) CommandName() string {
	return "add-service"
}

// Adds service to registry
func (c *AddServiceCommand) Apply(server raft.Server) (interface{}, error) {
	reg := server.Context().(registry.Registry)
	err := reg.Add(c.Service)

	if err == nil {
		log.Println("Added Service:", c.Service)
	}

	return c.Service, err
}

type UpdateTTLCommand struct {
	UUID    string
	TTL     uint32
	Expires time.Time
}

// NewUpdateTTLCommands returns a new UpdateTTLCommand
func NewUpdateTTLCommand(uuid string, ttl uint32) *UpdateTTLCommand {
	return &UpdateTTLCommand{uuid, ttl, getExpirationTime(ttl)}
}

// Name of command
func (c *UpdateTTLCommand) CommandName() string {
	return "update-ttl"
}

// Updates TTL in registry
func (c *UpdateTTLCommand) Apply(server raft.Server) (interface{}, error) {
	reg := server.Context().(registry.Registry)
	err := reg.UpdateTTL(c.UUID, c.TTL, c.Expires)

	if err == nil {
		log.Println("Updated Service TTL:", c.UUID, c.TTL)
	}

	return c.UUID, err
}

type RemoveServiceCommand struct {
	UUID string
}

// Creates a new RemoveServiceCommand
func NewRemoveServiceCommand(uuid string) *RemoveServiceCommand {
	return &RemoveServiceCommand{uuid}
}

// Name of command
func (c *RemoveServiceCommand) CommandName() string {
	return "remove-service"
}

// Removes service from the registry
func (c *RemoveServiceCommand) Apply(server raft.Server) (interface{}, error) {

	reg := server.Context().(registry.Registry)
	err := reg.RemoveUUID(c.UUID)

	if err == nil {
		log.Println("Removed Service:", c.UUID)
	}

	return c.UUID, err
}

func getExpirationTime(ttl uint32) time.Time {
	return time.Now().Add(time.Duration(ttl) * time.Second)
}

type AddCallbackCommand struct {
	Service msg.Service
	UUID    string // callback uuid
}

func NewAddCallbackCommand(s msg.Service, uuid string) *AddCallbackCommand {
	return &AddCallbackCommand{s, uuid}
}

// Name of command
func (c *AddCallbackCommand) CommandName() string {
	return "add-callback"
}

// Updates callback in registry
func (c *AddCallbackCommand) Apply(server raft.Server) (interface{}, error) {
	reg := server.Context().(registry.Registry)
	err := reg.AddCallback(c.Service, c.UUID)

	if err == nil {
		log.Println("Added Callback:", c.Service, c.UUID)
	}

	return c.Service, err
}

<commit_msg>Put these CommandName functions on a single line<commit_after>// Copyright (c) 2013 Erik St. Martin, Brian Ketelsen. All rights reserved.
// Use of this source code is governed by The MIT License (MIT) that can be
// found in the LICENSE file.

package server

import (
	"github.com/goraft/raft"
	"github.com/skynetservices/skydns/msg"
	"github.com/skynetservices/skydns/registry"
	"log"
	"time"
)

// Command for adding service to registry
type AddServiceCommand struct {
	Service msg.Service
}

// Creates a new AddServiceCommand
func NewAddServiceCommand(s msg.Service) *AddServiceCommand {
	s.Expires = getExpirationTime(s.TTL)

	return &AddServiceCommand{s}
}

// Name of command
func (c *AddServiceCommand) CommandName() string { return "add-service" }

// Adds service to registry
func (c *AddServiceCommand) Apply(server raft.Server) (interface{}, error) {
	reg := server.Context().(registry.Registry)
	err := reg.Add(c.Service)

	if err == nil {
		log.Println("Added Service:", c.Service)
	}

	return c.Service, err
}

type UpdateTTLCommand struct {
	UUID    string
	TTL     uint32
	Expires time.Time
}

// NewUpdateTTLCommands returns a new UpdateTTLCommand
func NewUpdateTTLCommand(uuid string, ttl uint32) *UpdateTTLCommand {
	return &UpdateTTLCommand{uuid, ttl, getExpirationTime(ttl)}
}

// Name of command
func (c *UpdateTTLCommand) CommandName() string { return "update-ttl" }

// Updates TTL in registry
func (c *UpdateTTLCommand) Apply(server raft.Server) (interface{}, error) {
	reg := server.Context().(registry.Registry)
	err := reg.UpdateTTL(c.UUID, c.TTL, c.Expires)

	if err == nil {
		log.Println("Updated Service TTL:", c.UUID, c.TTL)
	}

	return c.UUID, err
}

type RemoveServiceCommand struct {
	UUID string
}

// Creates a new RemoveServiceCommand
func NewRemoveServiceCommand(uuid string) *RemoveServiceCommand {
	return &RemoveServiceCommand{uuid}
}

// Name of command
func (c *RemoveServiceCommand) CommandName() string { return "remove-service" }

// Removes service from the registry
func (c *RemoveServiceCommand) Apply(server raft.Server) (interface{}, error) {

	reg := server.Context().(registry.Registry)
	err := reg.RemoveUUID(c.UUID)

	if err == nil {
		log.Println("Removed Service:", c.UUID)
	}

	return c.UUID, err
}

func getExpirationTime(ttl uint32) time.Time {
	return time.Now().Add(time.Duration(ttl) * time.Second)
}

type AddCallbackCommand struct {
	Service msg.Service
	UUID    string // callback uuid
}

func NewAddCallbackCommand(s msg.Service, uuid string) *AddCallbackCommand {
	return &AddCallbackCommand{s, uuid}
}

// Name of command
func (c *AddCallbackCommand) CommandName() string { return "add-callback" }

// Updates callback in registry
func (c *AddCallbackCommand) Apply(server raft.Server) (interface{}, error) {
	reg := server.Context().(registry.Registry)
	err := reg.AddCallback(c.Service, c.UUID)

	if err == nil {
		log.Println("Added Callback:", c.Service, c.UUID)
	}
	return c.Service, err
}
<|endoftext|>


<commit_before>/*
 *
 * k6 - a next-generation load testing tool
 * Copyright (C) 2017 Load Impact
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package cloud

import "fmt"

func URLForResults(refID string, cloudConfig Config) string {
        path := "runs"
        if cloudConfig.Token == "" {
                path = "anonymous"
        }
        return fmt.Sprintf("https://app.loadimpact.com/k6/%s/%s", path, refID)
}
<commit_msg>Rename `cloudConfig` to `config`<commit_after>/*
 *
 * k6 - a next-generation load testing tool
 * Copyright (C) 2017 Load Impact
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package cloud

import "fmt"

func URLForResults(refID string, config Config) string {
        path := "runs"
        if config.Token == "" {
                path = "anonymous"
        }
        return fmt.Sprintf("https://app.loadimpact.com/k6/%s/%s", path, refID)
}
<|endoftext|>


<commit_before>package server

import (
	"encoding/json"
	"fmt"
	sq "github.com/Masterminds/squirrel"
	log "github.com/Sirupsen/logrus"
	"github.com/getsentry/raven-go"
	"io/ioutil"
	"net/http"
)

// Maximum number of characters in a truncated description of a datum
// Used when obtaining and displaying many datum of a given structure
const truncationLength = 1024

// Default and maximum number of datum returned by bulk API queries
// Used when obtaining and displaying many datum of a given structure
const defaultNumResults = 30
const maxNumResults = 100

// Postgres Statement Builder instance
var psql = sq.StatementBuilder.PlaceholderFormat(sq.Dollar)

// Serve converts v to a JSON string and writes to w. Writes an
// HTTP 500 error on error.
func Serve(w http.ResponseWriter, v interface{}) {
	var marshaled []byte
	if v == nil {
		marshaled = []byte("{}")
	} else {
		var err error
		marshaled, err = json.Marshal(v)
		if err != nil {
			log.WithField("err", err).Error("Error while marshalling to JSON")
			raven.CaptureError(err, nil)
			http.Error(w, http.StatusText(500), 500)
			return
		}
	}

	w.Header().Set("Content-Type", "application/json;charset=utf-8")
	fmt.Fprint(w, string(marshaled))
}

// Serve404 returns a 404 code to w. It does not end the stream.
func Serve404(w http.ResponseWriter) {
	http.Error(w, http.StatusText(404), 404)
}

func ParseJSONFromBody(r *http.Request, v interface{}) error {
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return err
	}

	err = json.Unmarshal(body, v)
	if err != nil {
		return err
	}

	return nil
}

// formatRequest generates ascii representation of a request
// https://medium.com/doing-things-right/pretty-printing-http-requests-in-golang-a918d5aaa000
func PrettyPrintRequest(r *http.Request) string {
	// Create return string
	var request []string
	// Add the request string
	url := fmt.Sprintf("%v %v %v", r.Method, r.URL, r.Proto)
	request = append(request, url)
	// Add the host
	request = append(request, fmt.Sprintf("Host: %v", r.Host))
	// Loop through headers
	for name, headers := range r.Header {
		name = strings.ToLower(name)
		for _, h := range headers {
			request = append(request, fmt.Sprintf("%v: %v", name, h))
		}
	}

	// If this is a POST, add post data
	if r.Method == "POST" {
		r.ParseForm()
		request = append(request, "\n")
		request = append(request, r.Form.Encode())
	}
	// Return the request as a string
	return strings.Join(request, "\n")
}
<commit_msg>fix failing tests<commit_after>package server

import (
	"encoding/json"
	"fmt"
	sq "github.com/Masterminds/squirrel"
	log "github.com/Sirupsen/logrus"
	"github.com/getsentry/raven-go"
	"io/ioutil"
	"net/http"
	"strings"
)

// Maximum number of characters in a truncated description of a datum
// Used when obtaining and displaying many datum of a given structure
const truncationLength = 1024

// Default and maximum number of datum returned by bulk API queries
// Used when obtaining and displaying many datum of a given structure
const defaultNumResults = 30
const maxNumResults = 100

// Postgres Statement Builder instance
var psql = sq.StatementBuilder.PlaceholderFormat(sq.Dollar)

// Serve converts v to a JSON string and writes to w. Writes an
// HTTP 500 error on error.
func Serve(w http.ResponseWriter, v interface{}) {
	var marshaled []byte
	if v == nil {
		marshaled = []byte("{}")
	} else {
		var err error
		marshaled, err = json.Marshal(v)
		if err != nil {
			log.WithField("err", err).Error("Error while marshalling to JSON")
			raven.CaptureError(err, nil)
			http.Error(w, http.StatusText(500), 500)
			return
		}
	}

	w.Header().Set("Content-Type", "application/json;charset=utf-8")
	fmt.Fprint(w, string(marshaled))
}

// Serve404 returns a 404 code to w. It does not end the stream.
func Serve404(w http.ResponseWriter) {
	http.Error(w, http.StatusText(404), 404)
}

func ParseJSONFromBody(r *http.Request, v interface{}) error {
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return err
	}

	err = json.Unmarshal(body, v)
	if err != nil {
		return err
	}

	return nil
}

// formatRequest generates ascii representation of a request
// https://medium.com/doing-things-right/pretty-printing-http-requests-in-golang-a918d5aaa000
func PrettyPrintRequest(r *http.Request) string {
	// Create return string
	var request []string
	// Add the request string
	url := fmt.Sprintf("%v %v %v", r.Method, r.URL, r.Proto)
	request = append(request, url)
	// Add the host
	request = append(request, fmt.Sprintf("Host: %v", r.Host))
	// Loop through headers
	for name, headers := range r.Header {
		name = strings.ToLower(name)
		for _, h := range headers {
			request = append(request, fmt.Sprintf("%v: %v", name, h))
		}
	}

	// If this is a POST, add post data
	if r.Method == "POST" {
		r.ParseForm()
		request = append(request, "\n")
		request = append(request, r.Form.Encode())
	}
	// Return the request as a string
	return strings.Join(request, "\n")
}
<|endoftext|>


<commit_before>package osx

import (
	"fmt"
	"os"
	"path/filepath"
)

// TrashPath returns the path of the current user's trash
func TrashPath() string {
	return filepath.Join(os.Getenv("HOME"), ".Trash")
}

// Trash moves a file to the user's trash folder
func Trash(fileName string, verbose bool) error {

	if !fileExists(fileName) {
		return fmt.Errorf("File not found: %s\n", fileName)
	}

	trashPath := TrashPath()
	baseName := filepath.Base(fileName)
	dstName := filepath.Join(trashPath, baseName)

	i := 1
	for fileExists(dstName) {
		// come up with a new name
		dstName = filepath.Join(trashPath, baseName+fmt.Sprintf(" (copy %d)", i))
		i++
	}

	if verbose {
		fmt.Printf("Trashing %s => %s\n", fileName, dstName)
	}

	return os.Rename(fileName, dstName)
}

// reports whether the named file exists.
func fileExists(name string) bool {
	if _, err := os.Stat(name); err == nil {
		return true
	}
	return false
}
<commit_msg>unexport TrashPath<commit_after>package osx

import (
	"fmt"
	"os"
	"path/filepath"
)

// trashPath returns the path of the current user's trash
func trashPath() string {
	return filepath.Join(os.Getenv("HOME"), ".Trash")
}

// Trash moves a file to the trash folder
func Trash(fileName string, verbose bool) error {

	if !fileExists(fileName) {
		return fmt.Errorf("File not found: %s\n", fileName)
	}

	trashPath := trashPath()
	baseName := filepath.Base(fileName)
	dstName := filepath.Join(trashPath, baseName)

	i := 1
	for fileExists(dstName) {
		// come up with a new name
		dstName = filepath.Join(trashPath, baseName+fmt.Sprintf(" (copy %d)", i))
		i++
	}

	if verbose {
		fmt.Printf("Trashing %s => %s\n", fileName, dstName)
	}

	return os.Rename(fileName, dstName)
}

// reports whether the named file exists.
func fileExists(name string) bool {
	if _, err := os.Stat(name); err == nil {
		return true
	}
	return false
}
<|endoftext|>