<commit_before>package main

import (
	"path/filepath"
	"strings"
	"testing"
)

func getBaseTarget() *Target {
	target := &Target{
		File:          "./tests/<locale_code>.yml",
		ProjectID:     "project-id",
		AccessToken:   "access-token",
		FileFormat:    "yml",
		Params:        new(PullParams),
		RemoteLocales: getBaseLocales(),
	}
	return target
}

func TestPullPreconditions(t *testing.T) {
	target := getBaseTarget()
	for _, file := range []string{
		"",
		"no_extension",
		"./<locale_code>/<locale_code>.yml",
		"./**/**/en.yml",
		"./**/*/*/en.yml",
		"./**/*/en.yml",
		"./**/*/<locale_name>/<locale_code>/<tag>.yml",
	} {
		target.File = file
		if err := target.CheckPreconditions(); err == nil {
			t.Errorf("CheckPrecondition did not fail for pattern: '%s'", file)
		}
	}

	for _, file := range []string{
		"./<tag>/<locale_code>.yml",
		"./en.yml",
		"./<locale_name>/<locale_code>/<tag>.yml",
	} {
		target.File = file
		if err := target.CheckPreconditions(); err != nil {
			t.Errorf("CheckPrecondition should not fail with: %s", err.Error())
		}
	}
}

func TestTargetFields(t *testing.T) {
	target := getBaseTarget()

	if target.File != "./tests/<locale_code>.yml" {
		t.Errorf("Expected File to be %s and not %s", "./tests/<locale_code>.yml", target.File)
	}

	if target.AccessToken != "access-token" {
		t.Errorf("Expected AccesToken to be %s and not %s", "access-token", target.AccessToken)
	}

	if target.ProjectID != "project-id" {
		t.Errorf("Expected ProjectID to be %s and not %s", "project-id", target.ProjectID)
	}

	if target.FileFormat != "yml" {
		t.Errorf("Expected FileFormat to be %s and not %s", "yml", target.FileFormat)
	}

}

func TestTargetLocaleFiles(t *testing.T) {
	target := getBaseTarget()
	localeFiles, err := target.LocaleFiles()

	if err != nil {
		t.Errorf("Should not fail with: %s", err.Error())
	}

	enPath, _ := filepath.Abs("./tests/en.yml")
	dePath, _ := filepath.Abs("./tests/de.yml")
	expectedFiles := []*LocaleFile{
		&LocaleFile{
			Name: "english",
			Code:  "en",
			ID:   "en-locale-id",
			Path: enPath,
		},
		&LocaleFile{
			Name: "german",
			Code:  "de",
			ID:   "de-locale-id",
			Path: dePath,
		},
	}

	if len(localeFiles) == len(expectedFiles) {
		if err = compareLocaleFiles(localeFiles, expectedFiles); err != nil {
			t.Errorf(err.Error())
		}
	} else {
		t.Errorf("LocaleFiles should contain %v and not %v", expectedFiles, localeFiles)
	}
}

func TestReplacePlaceholders(t *testing.T) {
	target := getBaseTarget()
	target.File = "./<locale_code>/<tag>/<locale_name>.yml"
	localeFile := &LocaleFile{
		Name: "english",
		Code:  "en",
		ID:   "en-locale-id",
		Tag:  "abc",
		Path: "",
	}
	newPath, err := target.ReplacePlaceholders(localeFile)
	if err != nil {
		t.Errorf(err.Error())
		t.Fail()
	}

	if !strings.HasSuffix(newPath, "/en/abc/english.yml") {
		t.Errorf("Expected the new path to eql '%s' and not %s", "/en/abc/english.yml", newPath)
	}
}
<commit_msg>fix specs as wel<commit_after>package main

import (
	"path/filepath"
	"strings"
	"testing"
)

func getBaseTarget() *Target {
	target := &Target{
		File:          "./tests/<locale_code>.yml",
		ProjectID:     "project-id",
		AccessToken:   "access-token",
		FileFormat:    "yml",
		Params:        new(PullParams),
		RemoteLocales: getBaseLocales(),
	}
	return target
}

func TestPullPreconditions(t *testing.T) {
	target := getBaseTarget()
	for _, file := range []string{
		"",
		"no_extension",
		"./<locale_code>/<locale_code>.yml",
		"./**/**/en.yml",
		"./**/*/*/en.yml",
		"./**/*/en.yml",
		"./en.yml",
		"./**/*/<locale_name>/<locale_code>/<tag>.yml",
	} {
		target.File = file
		if err := target.CheckPreconditions(); err == nil {
			t.Errorf("CheckPrecondition did not fail for pattern: '%s'", file)
		}
	}

	for _, file := range []string{
		"./<tag>/<locale_code>.yml",
		"./<locale_name>/<locale_code>/<tag>.yml",
	} {
		target.File = file
		if err := target.CheckPreconditions(); err != nil {
			t.Errorf("CheckPrecondition should not fail with: %s", err.Error())
		}
	}
}

func TestTargetFields(t *testing.T) {
	target := getBaseTarget()

	if target.File != "./tests/<locale_code>.yml" {
		t.Errorf("Expected File to be %s and not %s", "./tests/<locale_code>.yml", target.File)
	}

	if target.AccessToken != "access-token" {
		t.Errorf("Expected AccesToken to be %s and not %s", "access-token", target.AccessToken)
	}

	if target.ProjectID != "project-id" {
		t.Errorf("Expected ProjectID to be %s and not %s", "project-id", target.ProjectID)
	}

	if target.FileFormat != "yml" {
		t.Errorf("Expected FileFormat to be %s and not %s", "yml", target.FileFormat)
	}

}

func TestTargetLocaleFiles(t *testing.T) {
	target := getBaseTarget()
	localeFiles, err := target.LocaleFiles()

	if err != nil {
		t.Errorf("Should not fail with: %s", err.Error())
	}

	enPath, _ := filepath.Abs("./tests/en.yml")
	dePath, _ := filepath.Abs("./tests/de.yml")
	expectedFiles := []*LocaleFile{
		&LocaleFile{
			Name: "english",
			Code: "en",
			ID:   "en-locale-id",
			Path: enPath,
		},
		&LocaleFile{
			Name: "german",
			Code: "de",
			ID:   "de-locale-id",
			Path: dePath,
		},
	}

	if len(localeFiles) == len(expectedFiles) {
		if err = compareLocaleFiles(localeFiles, expectedFiles); err != nil {
			t.Errorf(err.Error())
		}
	} else {
		t.Errorf("LocaleFiles should contain %v and not %v", expectedFiles, localeFiles)
	}
}

func TestReplacePlaceholders(t *testing.T) {
	target := getBaseTarget()
	target.File = "./<locale_code>/<tag>/<locale_name>.yml"
	localeFile := &LocaleFile{
		Name: "english",
		Code: "en",
		ID:   "en-locale-id",
		Tag:  "abc",
		Path: "",
	}
	newPath, err := target.ReplacePlaceholders(localeFile)
	if err != nil {
		t.Errorf(err.Error())
		t.Fail()
	}

	if !strings.HasSuffix(newPath, "/en/abc/english.yml") {
		t.Errorf("Expected the new path to eql '%s' and not %s", "/en/abc/english.yml", newPath)
	}
}
<|endoftext|>


<commit_before>package radix

import (
	"strings"
	"sync"
	"time"
)

var blockingCmds = map[string]bool{
	"WAIT": true,

	// taken from https://github.com/joomcode/redispipe#limitations
	"BLPOP":      true,
	"BRPOP":      true,
	"BRPOPLPUSH": true,

	"BZPOPMIN": true,
	"BZPOPMAX": true,

	"XREAD":      true,
	"XREADGROUP": true,

	"SAVE": true,
}

type pipeliner struct {
	c Client

	limit  int
	window time.Duration

	// reqsBufCh contains buffers for collecting commands and acts as a semaphore
	// to limit the number of concurrent flushes.
	reqsBufCh chan []CmdAction

	reqCh chan *pipelinerCmd
	reqWG sync.WaitGroup

	l      sync.RWMutex
	closed bool
}

var _ Client = (*pipeliner)(nil)

func newPipeliner(c Client, concurrency, limit int, window time.Duration) *pipeliner {
	if concurrency < 1 {
		concurrency = 1
	}

	p := &pipeliner{
		c: c,

		limit:  limit,
		window: window,

		reqsBufCh: make(chan []CmdAction, concurrency),

		reqCh: make(chan *pipelinerCmd, 32), // https://xkcd.com/221/
	}

	p.reqWG.Add(1)
	go func() {
		defer p.reqWG.Done()
		p.reqLoop()
	}()

	for i := 0; i < cap(p.reqsBufCh); i++ {
		if p.limit > 0 {
			p.reqsBufCh <- make([]CmdAction, 0, limit)
		} else {
			p.reqsBufCh <- nil
		}
	}

	return p
}

// CanDo checks if the given Action can be executed / passed to p.Do.
//
// If CanDo returns false, the Action must not be given to Do.
func (p *pipeliner) CanDo(a Action) bool {
	// there is currently no way to get the command for CmdAction implementations
	// from outside the radix package so we can not multiplex those commands. User
	// defined pipelines are not pipelined to let the user better control them.
	if cmdA, ok := a.(*cmdAction); ok {
		return !blockingCmds[strings.ToUpper(cmdA.cmd)]
	}
	return false
}

// Do executes the given Action as part of the pipeline.
//
// If a is not a CmdAction, Do panics.
func (p *pipeliner) Do(a Action) error {
	req := getPipelinerCmd(a.(CmdAction)) // get this outside the lock to avoid

	p.l.RLock()
	if p.closed {
		p.l.RUnlock()
		return errClientClosed
	}
	p.reqCh <- req
	p.l.RUnlock()

	err := <-req.resCh
	poolPipelinerCmd(req)
	return err
}

// Close closes the pipeliner and makes sure that all background goroutines
// are stopped before returning.
//
// Close does *not* close the underlying Client.
func (p *pipeliner) Close() error {
	p.l.Lock()
	defer p.l.Unlock()

	if p.closed {
		return nil
	}

	close(p.reqCh)
	p.reqWG.Wait()

	for i := 0; i < cap(p.reqsBufCh); i++ {
		<-p.reqsBufCh
	}

	p.c, p.closed = nil, true
	return nil
}

func (p *pipeliner) reqLoop() {
	t := getTimer(time.Hour)
	defer putTimer(t)

	t.Stop()

	reqs := <-p.reqsBufCh
	defer func() {
		p.reqsBufCh <- reqs
	}()

	for {
		select {
		case req, ok := <-p.reqCh:
			if !ok {
				reqs = p.flush(reqs)
				return
			}

			reqs = append(reqs, req)

			if p.limit > 0 && len(reqs) == p.limit {
				// if we reached the pipeline limit, execute now to avoid unnecessary waiting
				t.Stop()

				reqs = p.flush(reqs)
			} else if len(reqs) == 1 {
				t.Reset(p.window)
			}
		case <-t.C:
			reqs = p.flush(reqs)
		}
	}
}

func (p *pipeliner) flush(reqs []CmdAction) []CmdAction {
	if len(reqs) == 0 {
		return reqs
	}

	go func() {
		defer func() {
			p.reqsBufCh <- reqs[:0]
		}()

		pipe := pipelinerPipeline{
			pipeline: pipeline(reqs),
		}

		if err := p.c.Do(pipe); err != nil {
			for _, req := range reqs {
				req.(*pipelinerCmd).resCh <- err
			}
		}
	}()

	return <-p.reqsBufCh
}

type pipelinerCmd struct {
	CmdAction
	resCh chan error
}

var pipelinerCmdPool sync.Pool

func getPipelinerCmd(cmd CmdAction) *pipelinerCmd {
	req, _ := pipelinerCmdPool.Get().(*pipelinerCmd)
	if req != nil {
		req.CmdAction = cmd
		return req
	}
	return &pipelinerCmd{
		CmdAction: cmd,
		// using a buffer of 1 is faster than no buffer in most cases
		resCh: make(chan error, 1),
	}
}

func poolPipelinerCmd(req *pipelinerCmd) {
	req.CmdAction = nil
	pipelinerCmdPool.Put(req)
}

type pipelinerPipeline struct {
	pipeline
}

func (p pipelinerPipeline) Run(c Conn) error {
	if err := c.Encode(p); err != nil {
		return err
	}
	errConn := ioErrConn{Conn: c}
	for _, req := range p.pipeline {
		err := errConn.Decode(req)
		if errConn.lastIOErr != nil {
			return errConn.lastIOErr
		}
		req.(*pipelinerCmd).resCh <- err
	}
	return nil
}
<commit_msg>Add a comment that explains the order of statements in pipelinerPipeline.Run<commit_after>package radix

import (
	"strings"
	"sync"
	"time"
)

var blockingCmds = map[string]bool{
	"WAIT": true,

	// taken from https://github.com/joomcode/redispipe#limitations
	"BLPOP":      true,
	"BRPOP":      true,
	"BRPOPLPUSH": true,

	"BZPOPMIN": true,
	"BZPOPMAX": true,

	"XREAD":      true,
	"XREADGROUP": true,

	"SAVE": true,
}

type pipeliner struct {
	c Client

	limit  int
	window time.Duration

	// reqsBufCh contains buffers for collecting commands and acts as a semaphore
	// to limit the number of concurrent flushes.
	reqsBufCh chan []CmdAction

	reqCh chan *pipelinerCmd
	reqWG sync.WaitGroup

	l      sync.RWMutex
	closed bool
}

var _ Client = (*pipeliner)(nil)

func newPipeliner(c Client, concurrency, limit int, window time.Duration) *pipeliner {
	if concurrency < 1 {
		concurrency = 1
	}

	p := &pipeliner{
		c: c,

		limit:  limit,
		window: window,

		reqsBufCh: make(chan []CmdAction, concurrency),

		reqCh: make(chan *pipelinerCmd, 32), // https://xkcd.com/221/
	}

	p.reqWG.Add(1)
	go func() {
		defer p.reqWG.Done()
		p.reqLoop()
	}()

	for i := 0; i < cap(p.reqsBufCh); i++ {
		if p.limit > 0 {
			p.reqsBufCh <- make([]CmdAction, 0, limit)
		} else {
			p.reqsBufCh <- nil
		}
	}

	return p
}

// CanDo checks if the given Action can be executed / passed to p.Do.
//
// If CanDo returns false, the Action must not be given to Do.
func (p *pipeliner) CanDo(a Action) bool {
	// there is currently no way to get the command for CmdAction implementations
	// from outside the radix package so we can not multiplex those commands. User
	// defined pipelines are not pipelined to let the user better control them.
	if cmdA, ok := a.(*cmdAction); ok {
		return !blockingCmds[strings.ToUpper(cmdA.cmd)]
	}
	return false
}

// Do executes the given Action as part of the pipeline.
//
// If a is not a CmdAction, Do panics.
func (p *pipeliner) Do(a Action) error {
	req := getPipelinerCmd(a.(CmdAction)) // get this outside the lock to avoid

	p.l.RLock()
	if p.closed {
		p.l.RUnlock()
		return errClientClosed
	}
	p.reqCh <- req
	p.l.RUnlock()

	err := <-req.resCh
	poolPipelinerCmd(req)
	return err
}

// Close closes the pipeliner and makes sure that all background goroutines
// are stopped before returning.
//
// Close does *not* close the underlying Client.
func (p *pipeliner) Close() error {
	p.l.Lock()
	defer p.l.Unlock()

	if p.closed {
		return nil
	}

	close(p.reqCh)
	p.reqWG.Wait()

	for i := 0; i < cap(p.reqsBufCh); i++ {
		<-p.reqsBufCh
	}

	p.c, p.closed = nil, true
	return nil
}

func (p *pipeliner) reqLoop() {
	t := getTimer(time.Hour)
	defer putTimer(t)

	t.Stop()

	reqs := <-p.reqsBufCh
	defer func() {
		p.reqsBufCh <- reqs
	}()

	for {
		select {
		case req, ok := <-p.reqCh:
			if !ok {
				reqs = p.flush(reqs)
				return
			}

			reqs = append(reqs, req)

			if p.limit > 0 && len(reqs) == p.limit {
				// if we reached the pipeline limit, execute now to avoid unnecessary waiting
				t.Stop()

				reqs = p.flush(reqs)
			} else if len(reqs) == 1 {
				t.Reset(p.window)
			}
		case <-t.C:
			reqs = p.flush(reqs)
		}
	}
}

func (p *pipeliner) flush(reqs []CmdAction) []CmdAction {
	if len(reqs) == 0 {
		return reqs
	}

	go func() {
		defer func() {
			p.reqsBufCh <- reqs[:0]
		}()

		pipe := pipelinerPipeline{
			pipeline: pipeline(reqs),
		}

		if err := p.c.Do(pipe); err != nil {
			for _, req := range reqs {
				req.(*pipelinerCmd).resCh <- err
			}
		}
	}()

	return <-p.reqsBufCh
}

type pipelinerCmd struct {
	CmdAction
	resCh chan error
}

var pipelinerCmdPool sync.Pool

func getPipelinerCmd(cmd CmdAction) *pipelinerCmd {
	req, _ := pipelinerCmdPool.Get().(*pipelinerCmd)
	if req != nil {
		req.CmdAction = cmd
		return req
	}
	return &pipelinerCmd{
		CmdAction: cmd,
		// using a buffer of 1 is faster than no buffer in most cases
		resCh: make(chan error, 1),
	}
}

func poolPipelinerCmd(req *pipelinerCmd) {
	req.CmdAction = nil
	pipelinerCmdPool.Put(req)
}

type pipelinerPipeline struct {
	pipeline
}

func (p pipelinerPipeline) Run(c Conn) error {
	if err := c.Encode(p); err != nil {
		return err
	}
	errConn := ioErrConn{Conn: c}
	for _, req := range p.pipeline {
		err := errConn.Decode(req)
		// the order here is important: if we tried to send the error to
		// before returning we could end up sending the error twice, which
		// could lead to data races when the *pipelinerCmd gets reused.
		// to avoid this we must return without sending a value, in case
		// we got a non-recoverable error.
		if errConn.lastIOErr != nil {
			return errConn.lastIOErr
		}
		req.(*pipelinerCmd).resCh <- err
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import "fmt"

func main() {
	fmt.Println("Hello, world.")
}
<commit_msg>Use commands.<commit_after>package main

import (
	"commands"
)

func main() {
	commands.RootCmd.Execute()
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/xml"
	"errors"
	"fmt"
	"net"
	"net/http"
)

type Server struct {
	Type           string `xml:"type,attr"`
	Hostname       string `xml:"hostname"`
	Port           uint16 `xml:"port"`
	SocketType     string `xml:"socketType"`
	Authentication string `xml:"authentication"`
	Username       string `xml:"username"`
}
type IncomingServer struct {
	XMLName struct{} `xml:"incomingServer"`

	Server
}
type OutgoingServer struct {
	XMLName struct{} `xml:"outgoingServer"`

	Server
}

type Provider struct {
	XMLName struct{} `xml:"emailProvider"`

	Id               string `xml:"id,attr"`
	Domain           string `xml:"domain"`
	DisplayName      string `xml:"displayName"`
	DisplayShortName string `xml:"displayShortName"`

	IncomingServers []IncomingServer
	OutgoingServers []OutgoingServer
}

type ClientConfig struct {
	XMLName struct{} `xml:"clientConfig"`

	Version   string `xml:"version,attr"`
	Providers []Provider
}

// Lookup the given service, protocol pair in the domain SRV records.
func lookup(service, proto, domain string) (string, uint16, error) {
	_, addresses, err := net.LookupSRV(service, proto, domain)

	if err != nil {
		return "", 0, err
	}
	if len(addresses) == 0 {
		return "", 0, errors.New("No SRV records available for the given domain")
	}

	return addresses[0].Target, addresses[0].Port, nil
}

// Generate an autoconfig XML document based on the information obtained from
// querying the domain SRV records.
func generate_xml(domain string) (string, error) {
	// Incoming server.
	address_in, port_in, err := lookup("imaps", "tcp", domain)
	if err != nil {
		return "", err
	}

	incoming := IncomingServer{}
	incoming.Type = "imap"
	incoming.Hostname = address_in
	incoming.Port = port_in
	incoming.SocketType = "STARTTLS"
	incoming.Authentication = "password-encrypted"
	incoming.Username = "%EMAILADDRESS%"

	// Outgoing server.
	address_out, port_out, err := lookup("submission", "tcp", domain)
	if err != nil {
		return "", err
	}

	outgoing := OutgoingServer{}
	outgoing.Type = "smtp"
	outgoing.Hostname = address_out
	outgoing.Port = port_out
	outgoing.SocketType = "STARTTLS"
	outgoing.Authentication = "password-encrypted"
	outgoing.Username = "%EMAILADDRESS%"

	// Final data mangling.
	config := ClientConfig{
		Version: "1.1",
		Providers: []Provider{
			Provider{
				Id:               domain,
				Domain:           domain,
				DisplayName:      domain,
				DisplayShortName: domain,
				IncomingServers:  []IncomingServer{incoming},
				OutgoingServers:  []OutgoingServer{outgoing},
			},
		},
	}

	xmlconfig, err := xml.MarshalIndent(&config, "", "\t")
	if err != nil {
		return "", err
	}

	return string(xmlconfig), nil
}

func handler(w http.ResponseWriter, r *http.Request) {
	xmlconfig, err := generate_xml("marshland.ovh")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	fmt.Fprint(w, xml.Header, xmlconfig)
}

func main() {
	http.HandleFunc("/", handler)
	http.ListenAndServe(":9000", nil)
}
<commit_msg>Cast as late as possible.<commit_after>package main

import (
	"encoding/xml"
	"errors"
	"fmt"
	"net"
	"net/http"
)

type Server struct {
	Type           string `xml:"type,attr"`
	Hostname       string `xml:"hostname"`
	Port           uint16 `xml:"port"`
	SocketType     string `xml:"socketType"`
	Authentication string `xml:"authentication"`
	Username       string `xml:"username"`
}
type IncomingServer struct {
	XMLName struct{} `xml:"incomingServer"`

	Server
}
type OutgoingServer struct {
	XMLName struct{} `xml:"outgoingServer"`

	Server
}

type Provider struct {
	XMLName struct{} `xml:"emailProvider"`

	Id               string `xml:"id,attr"`
	Domain           string `xml:"domain"`
	DisplayName      string `xml:"displayName"`
	DisplayShortName string `xml:"displayShortName"`

	IncomingServers []IncomingServer
	OutgoingServers []OutgoingServer
}

type ClientConfig struct {
	XMLName struct{} `xml:"clientConfig"`

	Version   string `xml:"version,attr"`
	Providers []Provider
}

// Lookup the given service, protocol pair in the domain SRV records.
func lookup(service, proto, domain string) (string, uint16, error) {
	_, addresses, err := net.LookupSRV(service, proto, domain)

	if err != nil {
		return "", 0, err
	}
	if len(addresses) == 0 {
		return "", 0, errors.New("No SRV records available for the given domain")
	}

	return addresses[0].Target, addresses[0].Port, nil
}

// Generate an autoconfig XML document based on the information obtained from
// querying the domain SRV records.
func generate_xml(domain string) ([]byte, error) {
	// Incoming server.
	address_in, port_in, err := lookup("imaps", "tcp", domain)
	if err != nil {
		return nil, err
	}

	incoming := IncomingServer{}
	incoming.Type = "imap"
	incoming.Hostname = address_in
	incoming.Port = port_in
	incoming.SocketType = "STARTTLS"
	incoming.Authentication = "password-encrypted"
	incoming.Username = "%EMAILADDRESS%"

	// Outgoing server.
	address_out, port_out, err := lookup("submission", "tcp", domain)
	if err != nil {
		return nil, err
	}

	outgoing := OutgoingServer{}
	outgoing.Type = "smtp"
	outgoing.Hostname = address_out
	outgoing.Port = port_out
	outgoing.SocketType = "STARTTLS"
	outgoing.Authentication = "password-encrypted"
	outgoing.Username = "%EMAILADDRESS%"

	// Final data mangling.
	config := ClientConfig{
		Version: "1.1",
		Providers: []Provider{
			Provider{
				Id:               domain,
				Domain:           domain,
				DisplayName:      domain,
				DisplayShortName: domain,
				IncomingServers:  []IncomingServer{incoming},
				OutgoingServers:  []OutgoingServer{outgoing},
			},
		},
	}

	xmlconfig, err := xml.MarshalIndent(&config, "", "\t")
	if err != nil {
		return nil, err
	}

	return xmlconfig, nil
}

func handler(w http.ResponseWriter, r *http.Request) {
	xmlconfig, err := generate_xml("marshland.ovh")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	fmt.Fprint(w, xml.Header, string(xmlconfig))
}

func main() {
	http.HandleFunc("/", handler)
	http.ListenAndServe(":9000", nil)
}
<|endoftext|>


<commit_before>package perf

import (
	"bytes"
	"expvar"
	"fmt"
	"sync"
	"time"

	"github.com/anacrolix/missinggo"
)

var (
	em = missinggo.NewExpvarIndentMap("perfBuckets")
	mu sync.RWMutex
)

type Timer struct {
	started time.Time
}

func NewTimer() Timer {
	return Timer{time.Now()}
}

// var es = [...]string{"-9", "-8", "-7", "-6", "-5", "-4", "-3", "-2", "-1", "0", "1", "2"}

func bucketExponent(d time.Duration) int {
	e := -9
	for d != 0 {
		d /= 10
		e++
	}
	return e
}

type buckets struct {
	mu      sync.Mutex
	buckets []int64
}

func (me *buckets) Add(t time.Duration) {
	e := bucketExponent(t)
	me.mu.Lock()
	for e+9 >= len(me.buckets) {
		me.buckets = append(me.buckets, 0)
	}
	me.buckets[e+9]++
	me.mu.Unlock()
}

func (me *buckets) String() string {
	var b bytes.Buffer
	fmt.Fprintf(&b, "{")
	first := true
	me.mu.Lock()
	for i, count := range me.buckets {
		if first {
			if count == 0 {
				continue
			}
			first = false
		} else {
			fmt.Fprintf(&b, ", ")
		}
		fmt.Fprintf(&b, "%d: %d", i-9, count)
	}
	me.mu.Unlock()
	fmt.Fprintf(&b, "}")
	return b.String()
}

var _ expvar.Var = &buckets{}

func (t *Timer) Stop(desc string) time.Duration {
	d := time.Since(t.started)
	mu.RLock()
	_m := em.Get(desc)
	mu.RUnlock()
	var m *buckets
	if _m == nil {
		mu.Lock()
		_m = em.Get(desc)
		if _m == nil {
			m = new(buckets)
			em.Set(desc, m)
		}
		mu.Unlock()
	} else {
		m = _m.(*buckets)
	}
	m.Add(d)
	return d
}
<commit_msg>perf: Remove deadcode<commit_after>package perf

import (
	"bytes"
	"expvar"
	"fmt"
	"sync"
	"time"

	"github.com/anacrolix/missinggo"
)

var (
	em = missinggo.NewExpvarIndentMap("perfBuckets")
	mu sync.RWMutex
)

type Timer struct {
	started time.Time
}

func NewTimer() Timer {
	return Timer{time.Now()}
}

func bucketExponent(d time.Duration) int {
	e := -9
	for d != 0 {
		d /= 10
		e++
	}
	return e
}

type buckets struct {
	mu      sync.Mutex
	buckets []int64
}

func (me *buckets) Add(t time.Duration) {
	e := bucketExponent(t)
	me.mu.Lock()
	for e+9 >= len(me.buckets) {
		me.buckets = append(me.buckets, 0)
	}
	me.buckets[e+9]++
	me.mu.Unlock()
}

func (me *buckets) String() string {
	var b bytes.Buffer
	fmt.Fprintf(&b, "{")
	first := true
	me.mu.Lock()
	for i, count := range me.buckets {
		if first {
			if count == 0 {
				continue
			}
			first = false
		} else {
			fmt.Fprintf(&b, ", ")
		}
		fmt.Fprintf(&b, "%d: %d", i-9, count)
	}
	me.mu.Unlock()
	fmt.Fprintf(&b, "}")
	return b.String()
}

var _ expvar.Var = &buckets{}

func (t *Timer) Stop(desc string) time.Duration {
	d := time.Since(t.started)
	mu.RLock()
	_m := em.Get(desc)
	mu.RUnlock()
	var m *buckets
	if _m == nil {
		mu.Lock()
		_m = em.Get(desc)
		if _m == nil {
			m = new(buckets)
			em.Set(desc, m)
		}
		mu.Unlock()
	} else {
		m = _m.(*buckets)
	}
	m.Add(d)
	return d
}
<|endoftext|>


<commit_before>// Copyright 2016 Google Inc. All Rights Reserved.
// This file is available under the Apache license.

// Only build with go1.7 or above because b.Run did not exist before.
// +build go1.7

package main

import (
	"flag"
	"fmt"
	"io"
	"os"
	"testing"

	"github.com/google/mtail/mtail"
	"github.com/google/mtail/watcher"
	"github.com/spf13/afero"
)

var (
	recordBenchmark = flag.Bool("record_benchmark", false, "Record the benchmark results to 'benchmark_results.csv'.")
)

func BenchmarkProgram(b *testing.B) {
	// exampleProgramTests live in ex_test.go
	for _, bm := range exampleProgramTests {
		bm := bm
		b.Run(fmt.Sprintf("%s on %s", bm.programfile, bm.logfile), func(b *testing.B) {
			b.ReportAllocs()
			w := watcher.NewFakeWatcher()
			fs := afero.NewOsFs()
			fs = afero.NewCopyOnWriteFs(fs, afero.NewMemMapFs())
			log, err := fs.Create("/tmp/test.log")
			if err != nil {
				b.Fatalf("failed to create test file descriptor")
			}
			logs = []string{log.Name()}
			mtail, err := mtail.New(w, fs, mtail.ProgramPath(bm.programfile), mtail.LogPathPatterns(logs))
			if err != nil {
				b.Fatalf("Failed to create mtail: %s", err)
			}
			err = mtail.StartTailing()
			if err != nil {
				b.Fatalf("starttailing failed: %s", err)
			}

			var total int64
			b.ResetTimer()
			for i := 0; i < b.N; i++ {
				l, err := os.Open(bm.logfile)
				if err != nil {
					b.Fatalf("Couldn't open logfile: %s", err)
				}
				count, err := io.Copy(log, l)
				if err != nil {
					b.Fatalf("Write of test data failed to test file: %s", err)
				}
				total += count
				w.InjectUpdate(log.Name())
			}
			mtail.Close()
			b.StopTimer()
			b.SetBytes(total)
		})
	}
}
<commit_msg>Fix benchmark test.<commit_after>// Copyright 2016 Google Inc. All Rights Reserved.
// This file is available under the Apache license.

// Only build with go1.7 or above because b.Run did not exist before.
// +build go1.7

package main

import (
	"flag"
	"fmt"
	"io"
	"os"
	"testing"

	"github.com/google/mtail/metrics"
	"github.com/google/mtail/mtail"
	"github.com/google/mtail/watcher"
	"github.com/spf13/afero"
)

var (
	recordBenchmark = flag.Bool("record_benchmark", false, "Record the benchmark results to 'benchmark_results.csv'.")
)

func BenchmarkProgram(b *testing.B) {
	// exampleProgramTests live in ex_test.go
	for _, bm := range exampleProgramTests {
		bm := bm
		b.Run(fmt.Sprintf("%s on %s", bm.programfile, bm.logfile), func(b *testing.B) {
			b.ReportAllocs()
			w := watcher.NewFakeWatcher()
			fs := afero.NewOsFs()
			fs = afero.NewCopyOnWriteFs(fs, afero.NewMemMapFs())
			log, err := fs.Create("/tmp/test.log")
			if err != nil {
				b.Fatalf("failed to create test file descriptor")
			}
			logs = []string{log.Name()}
			store := metrics.NewStore()
			mtail, err := mtail.New(w, fs, mtail.ProgramPath(bm.programfile), mtail.LogPathPatterns(logs), mtail.Store(store))
			if err != nil {
				b.Fatalf("Failed to create mtail: %s", err)
			}
			err = mtail.StartTailing()
			if err != nil {
				b.Fatalf("starttailing failed: %s", err)
			}

			var total int64
			b.ResetTimer()
			for i := 0; i < b.N; i++ {
				l, err := os.Open(bm.logfile)
				if err != nil {
					b.Fatalf("Couldn't open logfile: %s", err)
				}
				count, err := io.Copy(log, l)
				if err != nil {
					b.Fatalf("Write of test data failed to test file: %s", err)
				}
				total += count
				w.InjectUpdate(log.Name())
			}
			mtail.Close()
			b.StopTimer()
			b.SetBytes(total)
		})
	}
}
<|endoftext|>


<commit_before>package golog

import "fmt"
import "strconv"
import "testing"
import "github.com/mndrix/golog/read"
import "github.com/mndrix/golog/term"

func BenchmarkTrue(b *testing.B) {
	m := NewMachine()
	g := read.Term_(`true.`)
	for i := 0; i < b.N; i++ {
		_ = m.ProveAll(g)
	}
}

func BenchmarkAppend(b *testing.B) {
	m := NewMachine().Consult(`
        append([], A, A).   % test same variable name as other clauses
        append([A|B], C, [A|D]) :-
            append(B, C, D).
    `)
	g := read.Term_(`append([a,b,c], [d,e], List).`)

	for i := 0; i < b.N; i++ {
		_ = m.ProveAll(g)
	}
}

// unify two compounds terms with deep structure. unification succeeds
func BenchmarkUnifyDeep(b *testing.B) {
	x := read.Term_(`a(b(c(d(e(f(g(h(i(j))))))))).`)
	y := read.Term_(`a(b(c(d(e(f(g(h(i(X))))))))).`)

	env := term.NewBindings()
	for i := 0; i < b.N; i++ {
		_, _ = x.Unify(env, y)
	}
}

// unify two compounds terms with deep structure. unification fails
func BenchmarkUnifyDeepFail(b *testing.B) {
	x := read.Term_(`a(b(c(d(e(f(g(h(i(j))))))))).`)
	y := read.Term_(`a(b(c(d(e(f(g(h(i(x))))))))).`)

	env := term.NewBindings()
	for i := 0; i < b.N; i++ {
		_, _ = x.Unify(env, y)
	}
}

func BenchmarkUnificationHash(b *testing.B) {
	x := read.Term_(`a(b(c(d(e(f(g(h(i(j))))))))).`)
	for i := 0; i < b.N; i++ {
		_ = term.UnificationHash([]term.Term{x}, 64, true)
	}
}

// test performance of a standard maplist implementation
func BenchmarkMaplist(b *testing.B) {
	m := NewMachine().Consult(`
        always_a(_, a).

        maplist(C, A, B) :-
            maplist_(A, B, C).

        maplist_([], [], _).
        maplist_([B|D], [C|E], A) :-
            call(A, B, C),
            maplist_(D, E, A).
    `)
	g := read.Term_(`maplist(always_a, [1,2,3,4,5], As).`)

	for i := 0; i < b.N; i++ {
		_ = m.ProveAll(g)
	}
}

// traditional, naive reverse benchmark
// The Art of Prolog by Sterling, etal says that reversing a 30 element
// list using this technique does 496 reductions.  From this we can
// calculate a rough measure of Golog's LIPS.
func BenchmarkNaiveReverse(b *testing.B) {
	m := NewMachine().Consult(`
        append([], A, A).
        append([A|B], C, [A|D]) :-
            append(B, C, D).

        reverse([],[]).
        reverse([X|Xs], Zs) :-
            reverse(Xs, Ys),
            append(Ys, [X], Zs).
    `)
	g := read.Term_(`reverse([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30], As).`)

	for i := 0; i < b.N; i++ {
		_ = m.ProveAll(g)
	}
}

func BenchmarkDCGish(b *testing.B) {
	m := NewMachine().Consult(`
        name([alice   |X], X).
        name([bob     |X], X).
        name([charles |X], X).
        name([david   |X], X).
        name([eric    |X], X).
        name([francis |X], X).
        name([george  |X], X).
        name([harry   |X], X).
        name([ignatius|X], X).
        name([john    |X], X).
        name([katie   |X], X).
        name([larry   |X], X).
        name([michael |X], X).
        name([nancy   |X], X).
        name([oliver  |X], X).
    `)
	g := read.Term_(`name([george,the,third], Rest).`)

	for i := 0; i < b.N; i++ {
		_ = m.ProveAll(g)
	}
}

func BenchmarkRead(b *testing.B) {
	for i := 0; i < b.N; i++ {
		_ = read.Term_(`reverse([1,2,3,4,5,6,7], Xs).`)
	}
}

// Low level benchmarks to test Go's implementation
func init() { // avoid import errors when low level benchmarks comment out
	_ = fmt.Sprintf("")
	_ = strconv.Itoa(1)
}

/*
func BenchmarkLowLevelCompareUint64(b *testing.B) {
    var nintendo uint64 = 282429536481
    var other uint64 = 387429489
    for i := 0; i < b.N; i++ {
        if nintendo == other {
            // do nothing
        }
    }
}
func BenchmarkLowLevelCompareString(b *testing.B) {
    nintendo := "nintendo"
    other := "other"
    for i := 0; i < b.N; i++ {
        if nintendo == other {
            // do nothing
        }
    }
}
func BenchmarkLowLevelBitwise(b *testing.B) {
    var nintendo uint64 = 282429536481
    var other uint64 = 387429489
    for i := 0; i < b.N; i++ {
        if nintendo & other == nintendo {
            // do nothing
        }
    }
}
func BenchmarkLowLevelFloatBinaryExponent(b *testing.B) {
	f := 3.1415
    for i := 0; i < b.N; i++ {
        _ = strconv.FormatFloat(f, 'b', 0, 64)
    }
}
func BenchmarkLowLevelFloatDecimalExponent(b *testing.B) {
	f := 3.1415
    for i := 0; i < b.N; i++ {
        _ = strconv.FormatFloat(f, 'e', 64, 64)
    }
}
func BenchmarkLowLevelIntDecimal(b *testing.B) {
	var x uint64 = 1967
    for i := 0; i < b.N; i++ {
        _ = fmt.Sprintf("%d", x)
    }
}
func BenchmarkLowLevelIntHex(b *testing.B) {
	var x uint64 = 1967
    for i := 0; i < b.N; i++ {
        _ = fmt.Sprintf("%x", x)
    }
}

// benchmarks to compare performance on interface-related code
type AnInterface interface {
    AMethod() int
}
type ImplementationOne int
func (*ImplementationOne) AMethod() int { return 1 }
type ImplementationTwo int
func (*ImplementationTwo) AMethod() int { return 2 }

func NotAMethod(x AnInterface) int {
    switch x.(type) {
        case *ImplementationOne:
            return 1
        case *ImplementationTwo:
            return 2
    }
    panic("impossible")
}

func NotAMethodManual(x AnInterface) int {
    kind := x.AMethod()
	switch kind {
        case 1:
            return 1
        case 2:
            return 2
    }
    panic("impossible")
}

// how expensive is it to call a method?
func BenchmarkInterfaceMethod(b *testing.B) {
    var x AnInterface
    num := 100
    x = (*ImplementationOne)(&num)

    for i := 0; i < b.N; i++ {
        _ = x.AMethod()
    }
}

// how expensive is it to call a function that acts like a method?
func BenchmarkInterfaceFunctionTypeSwitch(b *testing.B) {
    var x AnInterface
    num := 100
    x = (*ImplementationOne)(&num)

    for i := 0; i < b.N; i++ {
        _ = NotAMethod(x)
    }
}

// how expensive is it to call a function that acts like a method?
func BenchmarkInterfaceFunctionManualTypeSwitch(b *testing.B) {
    var x AnInterface
    num := 100
    x = (*ImplementationOne)(&num)

    for i := 0; i < b.N; i++ {
        _ = NotAMethodManual(x)
    }
}

// how expensive is it to inline a type switch that acts like a method?
func BenchmarkInterfaceInlineTypeSwitch(b *testing.B) {
    var x AnInterface
    num := 100
    x = (*ImplementationOne)(&num)

    for i := 0; i < b.N; i++ {
        var y int
        switch x.(type) {
            case *ImplementationOne:
                y = 1
            case *ImplementationTwo:
                y = 2
        }
        _ = y
    }
}

// how expensive is a manually-implemented type switch?
func BenchmarkInterfaceManualTypeSwitch(b *testing.B) {
    var x AnInterface
    num := 100
    x = (*ImplementationOne)(&num)

    for i := 0; i < b.N; i++ {
        var y int
        kind := x.AMethod()
        switch kind {
            case 1:
                y = 1
            case 2:
                y = 2
        }
        _ = y
    }
}

*/
<commit_msg>Format low level benchmarks<commit_after>package golog

import "fmt"
import "strconv"
import "testing"
import "github.com/mndrix/golog/read"
import "github.com/mndrix/golog/term"

func BenchmarkTrue(b *testing.B) {
	m := NewMachine()
	g := read.Term_(`true.`)
	for i := 0; i < b.N; i++ {
		_ = m.ProveAll(g)
	}
}

func BenchmarkAppend(b *testing.B) {
	m := NewMachine().Consult(`
        append([], A, A).   % test same variable name as other clauses
        append([A|B], C, [A|D]) :-
            append(B, C, D).
    `)
	g := read.Term_(`append([a,b,c], [d,e], List).`)

	for i := 0; i < b.N; i++ {
		_ = m.ProveAll(g)
	}
}

// unify two compounds terms with deep structure. unification succeeds
func BenchmarkUnifyDeep(b *testing.B) {
	x := read.Term_(`a(b(c(d(e(f(g(h(i(j))))))))).`)
	y := read.Term_(`a(b(c(d(e(f(g(h(i(X))))))))).`)

	env := term.NewBindings()
	for i := 0; i < b.N; i++ {
		_, _ = x.Unify(env, y)
	}
}

// unify two compounds terms with deep structure. unification fails
func BenchmarkUnifyDeepFail(b *testing.B) {
	x := read.Term_(`a(b(c(d(e(f(g(h(i(j))))))))).`)
	y := read.Term_(`a(b(c(d(e(f(g(h(i(x))))))))).`)

	env := term.NewBindings()
	for i := 0; i < b.N; i++ {
		_, _ = x.Unify(env, y)
	}
}

func BenchmarkUnificationHash(b *testing.B) {
	x := read.Term_(`a(b(c(d(e(f(g(h(i(j))))))))).`)
	for i := 0; i < b.N; i++ {
		_ = term.UnificationHash([]term.Term{x}, 64, true)
	}
}

// test performance of a standard maplist implementation
func BenchmarkMaplist(b *testing.B) {
	m := NewMachine().Consult(`
        always_a(_, a).

        maplist(C, A, B) :-
            maplist_(A, B, C).

        maplist_([], [], _).
        maplist_([B|D], [C|E], A) :-
            call(A, B, C),
            maplist_(D, E, A).
    `)
	g := read.Term_(`maplist(always_a, [1,2,3,4,5], As).`)

	for i := 0; i < b.N; i++ {
		_ = m.ProveAll(g)
	}
}

// traditional, naive reverse benchmark
// The Art of Prolog by Sterling, etal says that reversing a 30 element
// list using this technique does 496 reductions.  From this we can
// calculate a rough measure of Golog's LIPS.
func BenchmarkNaiveReverse(b *testing.B) {
	m := NewMachine().Consult(`
        append([], A, A).
        append([A|B], C, [A|D]) :-
            append(B, C, D).

        reverse([],[]).
        reverse([X|Xs], Zs) :-
            reverse(Xs, Ys),
            append(Ys, [X], Zs).
    `)
	g := read.Term_(`reverse([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30], As).`)

	for i := 0; i < b.N; i++ {
		_ = m.ProveAll(g)
	}
}

func BenchmarkDCGish(b *testing.B) {
	m := NewMachine().Consult(`
        name([alice   |X], X).
        name([bob     |X], X).
        name([charles |X], X).
        name([david   |X], X).
        name([eric    |X], X).
        name([francis |X], X).
        name([george  |X], X).
        name([harry   |X], X).
        name([ignatius|X], X).
        name([john    |X], X).
        name([katie   |X], X).
        name([larry   |X], X).
        name([michael |X], X).
        name([nancy   |X], X).
        name([oliver  |X], X).
    `)
	g := read.Term_(`name([george,the,third], Rest).`)

	for i := 0; i < b.N; i++ {
		_ = m.ProveAll(g)
	}
}

func BenchmarkRead(b *testing.B) {
	for i := 0; i < b.N; i++ {
		_ = read.Term_(`reverse([1,2,3,4,5,6,7], Xs).`)
	}
}

// Low level benchmarks to test Go's implementation
func init() { // avoid import errors when low level benchmarks comment out
	_ = fmt.Sprintf("")
	_ = strconv.Itoa(1)
}

/*
func BenchmarkLowLevelCompareUint64(b *testing.B) {
	var nintendo uint64 = 282429536481
	var other uint64 = 387429489
	for i := 0; i < b.N; i++ {
		if nintendo == other {
			// do nothing
		}
	}
}

func BenchmarkLowLevelCompareString(b *testing.B) {
	nintendo := "nintendo"
	other := "other"
	for i := 0; i < b.N; i++ {
		if nintendo == other {
			// do nothing
		}
	}
}
func BenchmarkLowLevelBitwise(b *testing.B) {
	var nintendo uint64 = 282429536481
	var other uint64 = 387429489
	for i := 0; i < b.N; i++ {
		if nintendo&other == nintendo {
			// do nothing
		}
	}
}
func BenchmarkLowLevelFloatBinaryExponent(b *testing.B) {
	f := 3.1415
	for i := 0; i < b.N; i++ {
		_ = strconv.FormatFloat(f, 'b', 0, 64)
	}
}
func BenchmarkLowLevelFloatDecimalExponent(b *testing.B) {
	f := 3.1415
	for i := 0; i < b.N; i++ {
		_ = strconv.FormatFloat(f, 'e', 64, 64)
	}
}
func BenchmarkLowLevelIntDecimal(b *testing.B) {
	var x uint64 = 1967
	for i := 0; i < b.N; i++ {
		_ = fmt.Sprintf("%d", x)
	}
}
func BenchmarkLowLevelIntHex(b *testing.B) {
	var x uint64 = 1967
	for i := 0; i < b.N; i++ {
		_ = fmt.Sprintf("%x", x)
	}
}

// benchmarks to compare performance on interface-related code
type AnInterface interface {
	AMethod() int
}
type ImplementationOne int

func (*ImplementationOne) AMethod() int { return 1 }

type ImplementationTwo int

func (*ImplementationTwo) AMethod() int { return 2 }

func NotAMethod(x AnInterface) int {
	switch x.(type) {
	case *ImplementationOne:
		return 1
	case *ImplementationTwo:
		return 2
	}
	panic("impossible")
}

func NotAMethodManual(x AnInterface) int {
	kind := x.AMethod()
	switch kind {
	case 1:
		return 1
	case 2:
		return 2
	}
	panic("impossible")
}

// how expensive is it to call a method?
func BenchmarkInterfaceMethod(b *testing.B) {
	var x AnInterface
	num := 100
	x = (*ImplementationOne)(&num)

	for i := 0; i < b.N; i++ {
		_ = x.AMethod()
	}
}

// how expensive is it to call a function that acts like a method?
func BenchmarkInterfaceFunctionTypeSwitch(b *testing.B) {
	var x AnInterface
	num := 100
	x = (*ImplementationOne)(&num)

	for i := 0; i < b.N; i++ {
		_ = NotAMethod(x)
	}
}

// how expensive is it to call a function that acts like a method?
func BenchmarkInterfaceFunctionManualTypeSwitch(b *testing.B) {
	var x AnInterface
	num := 100
	x = (*ImplementationOne)(&num)

	for i := 0; i < b.N; i++ {
		_ = NotAMethodManual(x)
	}
}

// how expensive is it to inline a type switch that acts like a method?
func BenchmarkInterfaceInlineTypeSwitch(b *testing.B) {
	var x AnInterface
	num := 100
	x = (*ImplementationOne)(&num)

	for i := 0; i < b.N; i++ {
		var y int
		switch x.(type) {
		case *ImplementationOne:
			y = 1
		case *ImplementationTwo:
			y = 2
		}
		_ = y
	}
}

// how expensive is a manually-implemented type switch?
func BenchmarkInterfaceManualTypeSwitch(b *testing.B) {
	var x AnInterface
	num := 100
	x = (*ImplementationOne)(&num)

	for i := 0; i < b.N; i++ {
		var y int
		kind := x.AMethod()
		switch kind {
		case 1:
			y = 1
		case 2:
			y = 2
		}
		_ = y
	}
}

*/
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"fmt"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strconv"

	"github.com/gorilla/mux"
	"github.com/gorilla/websocket"
	_ "github.com/lib/pq"
)

// Address struct is the response returned after a request for addresses
type Address struct {
	PLZ, Gemeindename, Ortsname, Strassenname, Hausnr *string
	LatlongX, LatlongY                                *float64
}

var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool { return true },
}

type connection struct {
	*sql.DB
}

const maxrowsFTS = 200
const defaultrowsFTS = 25
const nearbymeters = 50 // default distance to search nearby addresses in meter
const autocomplete = `search @@ plainto_tsquery('german', $1 || ':*')`
const noautocomplete = `search @@ plainto_tsquery('german', $1)`

const fulltextSearchSQL = `select addritems.plz, addritems.gemeindename, addritems.ortsname, addritems.strassenname, addritems.hausnrzahl1, ST_Y(adresse.latlong), ST_X(adresse.latlong)
from adresse
inner join addritems
on addritems.adrcd = adresse.adrcd
and %s
and addritems.plz like COALESCE(NULLIF($2, ''), addritems.plz)
and addritems.gkz like COALESCE(NULLIF($3, ''), addritems.gkz)
and addritems.bld = COALESCE(CAST(NULLIF($4, '') AS smallint), addritems.bld)
and CASE ($5 = '' AND $6='') WHEN NOT FALSE THEN TRUE ELSE ST_DWithin(latlong_g, ST_GeomFromText('POINT(' || $5 || ' ' || $6 || ')', 4326)::geography, $7, false) END
limit $8`

func (con *connection) fulltextSearch(w http.ResponseWriter, r *http.Request) {

	var n uint64
	if nrows := r.URL.Query().Get("n"); nrows != "" {
		var err error
		if n, err = strconv.ParseUint(nrows, 10, 8); err != nil {
			s := "error when parsing parameter n: " + err.Error()
			info(s)
			http.Error(w, s, http.StatusBadRequest)
			return
		}
		if n > maxrowsFTS {
			s := "paramter out of range"
			info(s)
			http.Error(w, s, http.StatusBadRequest)
			return
		}
	} else {
		n = defaultrowsFTS
	}

	lat := r.URL.Query().Get("lat")
	lon := r.URL.Query().Get("lon")

	if (len(lat) > 0) != (len(lon) > 0) { // Latitude/Longitude: either both parameters are set or none of the two is set
		s := "lat/lon: either both parameters are set to a value or both have to be empty"
		info(s)
		http.Error(w, s, http.StatusBadRequest)
		return
	}

	q := r.URL.Query().Get("q")
	postcode := r.URL.Query().Get("postcode")
	citycode := r.URL.Query().Get("citycode")
	province := r.URL.Query().Get("province")

	var querystring string
	if acparam := r.URL.Query().Get("autocomplete"); acparam == "0" {
		querystring = fmt.Sprintf(fulltextSearchSQL, noautocomplete)
	} else {
		querystring = fmt.Sprintf(fulltextSearchSQL, autocomplete)
	}

	rows, err := con.Query(querystring, q, postcode, citycode, province, lat, lon, nearbymeters, n)
	if err != nil {
		s := "database query failed: " + err.Error()
		info(s)
		http.Error(w, s, http.StatusInternalServerError)
		return
	}
	defer rows.Close()
	var plz, gemeindename, ortsname, strassenname, hausnrzahl1 *string
	var latlongy, latlongx *float64

	var addresses []Address

	for rows.Next() {
		if err = rows.Scan(&plz, &gemeindename, &ortsname, &strassenname, &hausnrzahl1, &latlongy, &latlongx); err != nil {
			s := "reading from database failed: " + err.Error()
			info(s)
			http.Error(w, s, http.StatusInternalServerError)
			return
		}

		addr := Address{PLZ: plz, Gemeindename: gemeindename, Ortsname: ortsname, Strassenname: strassenname, Hausnr: hausnrzahl1, LatlongY: latlongy, LatlongX: latlongx}
		addresses = append(addresses, addr)
	}

	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		s := "connection upgrade to websocket failed: " + err.Error()
		info(s)
		http.Error(w, s, http.StatusInternalServerError)
		return
	}

	conn.WriteJSON(addresses)
	conn.Close()
}

func getDatabaseConnection() (*sql.DB, error) {
	var dburl string

	if dburl = os.Getenv("DATABASE_URL"); dburl == "" {
		dburl = "postgres://"
	}

	db, err := sql.Open("postgres", dburl)
	if err != nil {
		return nil, err
	}
	return db, nil
}

func main() {
	currdir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
	info("starting up in " + currdir)

	conn, err := getDatabaseConnection()
	if err != nil {
		fatal(err.Error())
	}
	connection := &connection{DB: conn}

	r := mux.NewRouter()
	s := r.PathPrefix("/ws/").Subrouter()
	s.HandleFunc("/address/fts", connection.fulltextSearch)

	var port, secport string
	if secport = os.Getenv("SECPORT"); secport != "" {
		go func() {
			if err := http.ListenAndServeTLS(":"+secport, "cert.pem", "key.pem", r); err != nil {
				fatal("secure serving failed: " + err.Error())
			}
		}()
		info("serving securely on port " + secport)
	}

	if port = os.Getenv("PORT"); port == "" {
		port = "5000"
	}

	info("serving on port " + port)
	http.ListenAndServe(":"+port, r)
}

// Log wrappers
func info(template string, values ...interface{}) {
	log.Printf("[bevaddress][info] "+template+"\n", values...)
}

func fatal(template string, values ...interface{}) {
	log.Fatalf("[bevaddress][fatal] "+template+"\n", values...)
}
<commit_msg>Fixed auto completion<commit_after>package main

import (
	"database/sql"
	"fmt"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strconv"

	"github.com/gorilla/mux"
	"github.com/gorilla/websocket"
	_ "github.com/lib/pq"
)

// Address struct is the response returned after a request for addresses
type Address struct {
	PLZ, Gemeindename, Ortsname, Strassenname, Hausnr *string
	LatlongX, LatlongY                                *float64
}

var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool { return true },
}

type connection struct {
	*sql.DB
}

const maxrowsFTS = 200
const defaultrowsFTS = 25
const nearbymeters = 50 // default distance to search nearby addresses in meter
const autocomplete = `search @@ (plainto_tsquery('german', $1)::text || ':*')::tsquery`
const noautocomplete = `search @@ plainto_tsquery('german', $1)`

const fulltextSearchSQL = `select addritems.plz, addritems.gemeindename, addritems.ortsname, addritems.strassenname, addritems.hausnrzahl1, ST_Y(adresse.latlong), ST_X(adresse.latlong)
from adresse
inner join addritems
on addritems.adrcd = adresse.adrcd
and %s
and addritems.plz like COALESCE(NULLIF($2, ''), addritems.plz)
and addritems.gkz like COALESCE(NULLIF($3, ''), addritems.gkz)
and addritems.bld = COALESCE(CAST(NULLIF($4, '') AS smallint), addritems.bld)
and CASE ($5 = '' AND $6='') WHEN NOT FALSE THEN TRUE ELSE ST_DWithin(latlong_g, ST_GeomFromText('POINT(' || $5 || ' ' || $6 || ')', 4326)::geography, $7, false) END
limit $8`

func (con *connection) fulltextSearch(w http.ResponseWriter, r *http.Request) {

	var n uint64
	if nrows := r.URL.Query().Get("n"); nrows != "" {
		var err error
		if n, err = strconv.ParseUint(nrows, 10, 8); err != nil {
			s := "error when parsing parameter n: " + err.Error()
			info(s)
			http.Error(w, s, http.StatusBadRequest)
			return
		}
		if n > maxrowsFTS {
			s := "paramter out of range"
			info(s)
			http.Error(w, s, http.StatusBadRequest)
			return
		}
	} else {
		n = defaultrowsFTS
	}

	lat := r.URL.Query().Get("lat")
	lon := r.URL.Query().Get("lon")

	if (len(lat) > 0) != (len(lon) > 0) { // Latitude/Longitude: either both parameters are set or none of the two is set
		s := "lat/lon: either both parameters are set to a value or both have to be empty"
		info(s)
		http.Error(w, s, http.StatusBadRequest)
		return
	}

	q := r.URL.Query().Get("q")
	postcode := r.URL.Query().Get("postcode")
	citycode := r.URL.Query().Get("citycode")
	province := r.URL.Query().Get("province")

	var querystring string
	if acparam := r.URL.Query().Get("autocomplete"); acparam == "0" {
		querystring = fmt.Sprintf(fulltextSearchSQL, noautocomplete)
	} else {
		querystring = fmt.Sprintf(fulltextSearchSQL, autocomplete)
	}

	rows, err := con.Query(querystring, q, postcode, citycode, province, lat, lon, nearbymeters, n)
	if err != nil {
		s := "database query failed: " + err.Error()
		info(s)
		http.Error(w, s, http.StatusInternalServerError)
		return
	}
	defer rows.Close()
	var plz, gemeindename, ortsname, strassenname, hausnrzahl1 *string
	var latlongy, latlongx *float64

	var addresses []Address

	for rows.Next() {
		if err = rows.Scan(&plz, &gemeindename, &ortsname, &strassenname, &hausnrzahl1, &latlongy, &latlongx); err != nil {
			s := "reading from database failed: " + err.Error()
			info(s)
			http.Error(w, s, http.StatusInternalServerError)
			return
		}

		addr := Address{PLZ: plz, Gemeindename: gemeindename, Ortsname: ortsname, Strassenname: strassenname, Hausnr: hausnrzahl1, LatlongY: latlongy, LatlongX: latlongx}
		addresses = append(addresses, addr)
	}

	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		s := "connection upgrade to websocket failed: " + err.Error()
		info(s)
		http.Error(w, s, http.StatusInternalServerError)
		return
	}

	conn.WriteJSON(addresses)
	conn.Close()
}

func getDatabaseConnection() (*sql.DB, error) {
	var dburl string

	if dburl = os.Getenv("DATABASE_URL"); dburl == "" {
		dburl = "postgres://"
	}

	db, err := sql.Open("postgres", dburl)
	if err != nil {
		return nil, err
	}
	return db, nil
}

func main() {
	currdir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
	info("starting up in " + currdir)

	conn, err := getDatabaseConnection()
	if err != nil {
		fatal(err.Error())
	}
	connection := &connection{DB: conn}

	r := mux.NewRouter()
	s := r.PathPrefix("/ws/").Subrouter()
	s.HandleFunc("/address/fts", connection.fulltextSearch)

	var port, secport string
	if secport = os.Getenv("SECPORT"); secport != "" {
		go func() {
			if err := http.ListenAndServeTLS(":"+secport, "cert.pem", "key.pem", r); err != nil {
				fatal("secure serving failed: " + err.Error())
			}
		}()
		info("serving securely on port " + secport)
	}

	if port = os.Getenv("PORT"); port == "" {
		port = "5000"
	}

	info("serving on port " + port)
	http.ListenAndServe(":"+port, r)
}

// Log wrappers
func info(template string, values ...interface{}) {
	log.Printf("[bevaddress][info] "+template+"\n", values...)
}

func fatal(template string, values ...interface{}) {
	log.Fatalf("[bevaddress][fatal] "+template+"\n", values...)
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"os"
	"runtime"
	"runtime/pprof"
)

func startProfiling() func() {
	if isProfileEnabled("cpu") {
		f, err := os.Create("cpu.pprof")
		if err != nil {
			log.Fatalln(err)
		}
		if err := pprof.StartCPUProfile(f); err != nil {
			log.Fatalln(err)
		}
	}
	if isProfileEnabled("block") {
		runtime.SetBlockProfileRate(1)
	}

	return dumpProfiles
}

func isProfileEnabled(profile string) bool {
	for _, p := range *profiles {
		if p == profile {
			return true
		}
	}
	return false
}

func dumpProfiles() {
	for _, p := range *profiles {
		dumpProfile(p)
	}
}

func dumpProfile(p string) {
	if p == "cpu" {
		pprof.StopCPUProfile()
		return
	}

	f, err := os.Create(p + ".pprof")
	if err != nil {
		log.Fatalln(err)
	}
	defer func() {
		if err = f.Close(); err != nil {
			log.Fatalln("Could not close profile", p, err)
		}
	}()

	prof := pprof.Lookup(p)

	if prof != nil {
		// print symbolic names in profile to make them human-readable
		err = prof.WriteTo(f, 1)
		if err != nil {
			log.Fatalln(err)
		}
	}
}
<commit_msg>enhance accuracy of heap profiling<commit_after>package main

import (
	"log"
	"os"
	"runtime"
	"runtime/pprof"
)

func startProfiling() func() {
	if isProfileEnabled("cpu") {
		f, err := os.Create("cpu.pprof")
		if err != nil {
			log.Fatalln(err)
		}
		if err := pprof.StartCPUProfile(f); err != nil {
			log.Fatalln(err)
		}
	}
	if isProfileEnabled("block") {
		runtime.SetBlockProfileRate(1)
	}
	if isProfileEnabled("heap") {
		runtime.MemProfileRate = 16 * 1024
	}

	return dumpProfiles
}

func isProfileEnabled(profile string) bool {
	for _, p := range *profiles {
		if p == profile {
			return true
		}
	}
	return false
}

func dumpProfiles() {
	for _, p := range *profiles {
		dumpProfile(p)
	}
}

func dumpProfile(p string) {
	if p == "cpu" {
		pprof.StopCPUProfile()
		return
	}

	f, err := os.Create(p + ".pprof")
	if err != nil {
		log.Fatalln(err)
	}
	defer func() {
		if err = f.Close(); err != nil {
			log.Fatalln("Could not close profile", p, err)
		}
	}()

	prof := pprof.Lookup(p)

	if prof != nil {
		// print symbolic names in profile to make them human-readable
		err = prof.WriteTo(f, 1)
		if err != nil {
			log.Fatalln(err)
		}
	}
}
<|endoftext|>


<commit_before>package pool

import (
	"io"
	"net"
	"os"
	"time"
)

func ExamplePool() {
	go func() {
		if l, err := net.Listen("tcp", "localhost:10000"); err == nil {
			p := NewPool(l.Accept)
			for {
				if c, err := p.Get(); err == nil {
					go func() {
						io.Copy(os.Stdout, c)
						c.Close()
					}()
					// Output:
					// hello world
					// hello world
					// hello world
					// hello world
					// hello world
					// hello world
				}
			}
		}
	}()

	p := NewPool(PoolLimiter(func() (net.Conn, error) {
		return net.Dial("tcp", "localhost:10000")
	}, 3))

	for i := 0; i < 6; i++ {
		if c, err := p.Get(); err == nil {
			c.Write([]byte("hello world\n"))
			go func() {
				<-time.After(100 * time.Millisecond)
				c.Close()
			}()
		}
	}

	<-time.After(100 * time.Millisecond)
}
<commit_msg>fixed test<commit_after>package pool

import (
	"io"
	"net"
	"os"
	"time"
)

func ExamplePool() {
	go func() {
		if l, err := net.Listen("tcp", "localhost:10000"); err == nil {
			p := NewPool(l.Accept)
			for {
				if c, err := p.Get(); err == nil {
					go func() {
						io.Copy(os.Stdout, c)
						c.Close()
					}()
					// Output:
					// hello world
					// hello world
					// hello world
					// hello world
					// hello world
					// hello world
				}
			}
		}
	}()

	p := NewPool(Limiter(func() (net.Conn, error) {
		return net.Dial("tcp", "localhost:10000")
	}, 3))

	for i := 0; i < 6; i++ {
		if c, err := p.Get(); err == nil {
			c.Write([]byte("hello world\n"))
			go func() {
				<-time.After(100 * time.Millisecond)
				c.Close()
			}()
		}
	}

	<-time.After(100 * time.Millisecond)
}
<|endoftext|>


<commit_before>package gonvim

import (
	"time"

	"github.com/dzhou121/ui"
)

// PopupMenu is the popupmenu
type PopupMenu struct {
	box    *ui.Box
	items  []*PopupItem
	total  int
	hidden bool
}

// PopupItem is
type PopupItem struct {
	kind *SpanHandler
	menu *SpanHandler
}

func initPopupmenu() *PopupMenu {
	total := 10
	box := ui.NewHorizontalBox()
	var popupItems []*PopupItem
	for i := 0; i < total; i++ {
		kindSpanHandler := &SpanHandler{}
		kindSpan := ui.NewArea(kindSpanHandler)
		kindSpanHandler.span = kindSpan

		menuSpanHandler := &SpanHandler{}
		menuSpan := ui.NewArea(menuSpanHandler)
		menuSpanHandler.span = menuSpan

		popupItem := &PopupItem{
			kind: kindSpanHandler,
			menu: menuSpanHandler,
		}

		popupItems = append(popupItems, popupItem)
		box.Append(kindSpan, false)
		box.Append(menuSpan, false)
	}
	box.SetShadow(0, 2, 0, 0, 0, 1, 4)
	box.Hide()

	return &PopupMenu{
		box:   box,
		items: popupItems,
		total: total,
	}
}

func (p *PopupMenu) show(args []interface{}) {
	p.hidden = false
	arg := args[0].([]interface{})
	items := arg[0].([]interface{})
	selected := reflectToInt(arg[1])
	row := reflectToInt(arg[2])
	col := reflectToInt(arg[3])

	popupItems := p.items
	i := 0
	kindWidth := 0
	menuWidthMax := 0
	heightSum := 0
	height := 0
	for i = 0; i < p.total; i++ {
		popupItem := popupItems[i]
		if i >= len(items) {
			popupItem.hide()
			continue
		}

		item := items[i].([]interface{})
		popupItem.setItem(item, selected == i)

		var menuWidth int
		menuWidth, height = popupItem.menu.getSize()
		kindWidth, height = popupItem.kind.getSize()

		if menuWidth > menuWidthMax {
			menuWidthMax = menuWidth
		}
		y := heightSum
		heightSum += height
		ui.QueueMain(func() {
			popupItem.kind.span.SetPosition(0, y)
			popupItem.menu.span.SetPosition(kindWidth, y)
		})
	}

	for i = 0; i < p.total; i++ {
		if i >= len(items) {
			continue
		}
		popupItem := popupItems[i]
		ui.QueueMain(func() {
			popupItem.kind.span.SetSize(kindWidth, height)
			popupItem.kind.span.Show()
			popupItem.kind.span.QueueRedrawAll()
			popupItem.menu.span.SetSize(menuWidthMax, height)
			popupItem.menu.span.Show()
			popupItem.menu.span.QueueRedrawAll()
		})
	}

	ui.QueueMain(func() {
		p.box.SetPosition(
			col*editor.font.width-kindWidth-p.items[0].menu.paddingLeft,
			(row+1)*editor.font.lineHeight,
		)
		p.box.SetSize(menuWidthMax+kindWidth, heightSum)
		p.box.Show()
	})
}

func (p *PopupMenu) hide(args []interface{}) {
	p.hidden = true

	time.AfterFunc(50*time.Millisecond, func() {
		if p.hidden {
			ui.QueueMain(func() {
				p.box.Hide()
			})
		}
	})
}

func (p *PopupMenu) selectItem(args []interface{}) {
	selected := reflectToInt(args[0].([]interface{})[0])
	for i := 0; i < p.total; i++ {
		popupItem := p.items[i]
		if selected == i {
			popupItem.menu.SetBackground(newRGBA(81, 154, 186, 1))
			ui.QueueMain(func() {
				popupItem.menu.span.QueueRedrawAll()
			})
		} else {
			popupItem.menu.SetBackground(newRGBA(14, 17, 18, 1))
			ui.QueueMain(func() {
				popupItem.menu.span.QueueRedrawAll()
			})
		}
	}
}

func (p *PopupItem) setItem(item []interface{}, selected bool) {
	text := item[0].(string)
	kindText := item[1].(string)
	p.setKind(kindText, selected)

	fg := newRGBA(205, 211, 222, 1)
	p.menu.SetColor(fg)
	if selected {
		p.menu.SetBackground(newRGBA(81, 154, 186, 1))
	} else {
		p.menu.SetBackground(newRGBA(14, 17, 18, 1))
	}
	p.menu.SetFont(editor.font.font)
	p.menu.SetText(text)

	p.menu.paddingLeft = 10
	p.menu.paddingRight = 10
	p.menu.paddingTop = 8
	p.menu.paddingBottom = 8

	p.kind.paddingLeft = 10
	p.kind.paddingRight = 10
	p.kind.paddingTop = 8
	p.kind.paddingBottom = 8
}

func (p *PopupItem) setKind(kindText string, selected bool) {
	color := newRGBA(151, 195, 120, 1)
	bg := newRGBA(151, 195, 120, 0.2)

	switch kindText {
	case "function":
		kindText = "f"
		color = newRGBA(97, 174, 239, 1)
		bg = newRGBA(97, 174, 239, 0.2)
	case "func":
		kindText = "f"
		color = newRGBA(97, 174, 239, 1)
		bg = newRGBA(97, 174, 239, 0.2)
	default:
		kindText = "b"
	}
	p.kind.SetColor(color)
	p.kind.SetBackground(bg)
	p.kind.SetFont(editor.font.font)
	p.kind.SetText(kindText)
}

func (p *PopupItem) hide() {
	ui.QueueMain(func() {
		p.kind.span.Hide()
		p.menu.span.Hide()
	})
}
<commit_msg>some more color for popupmenu kind<commit_after>package gonvim

import (
	"time"

	"github.com/dzhou121/ui"
)

// PopupMenu is the popupmenu
type PopupMenu struct {
	box    *ui.Box
	items  []*PopupItem
	total  int
	hidden bool
}

// PopupItem is
type PopupItem struct {
	kind *SpanHandler
	menu *SpanHandler
}

func initPopupmenu() *PopupMenu {
	total := 10
	box := ui.NewHorizontalBox()
	var popupItems []*PopupItem
	for i := 0; i < total; i++ {
		kindSpanHandler := &SpanHandler{}
		kindSpan := ui.NewArea(kindSpanHandler)
		kindSpanHandler.span = kindSpan

		menuSpanHandler := &SpanHandler{}
		menuSpan := ui.NewArea(menuSpanHandler)
		menuSpanHandler.span = menuSpan

		popupItem := &PopupItem{
			kind: kindSpanHandler,
			menu: menuSpanHandler,
		}

		popupItems = append(popupItems, popupItem)
		box.Append(kindSpan, false)
		box.Append(menuSpan, false)
	}
	box.SetShadow(0, 2, 0, 0, 0, 1, 4)
	box.Hide()

	return &PopupMenu{
		box:   box,
		items: popupItems,
		total: total,
	}
}

func (p *PopupMenu) show(args []interface{}) {
	p.hidden = false
	arg := args[0].([]interface{})
	items := arg[0].([]interface{})
	selected := reflectToInt(arg[1])
	row := reflectToInt(arg[2])
	col := reflectToInt(arg[3])

	popupItems := p.items
	i := 0
	kindWidth := 0
	menuWidthMax := 0
	heightSum := 0
	height := 0
	for i = 0; i < p.total; i++ {
		popupItem := popupItems[i]
		if i >= len(items) {
			popupItem.hide()
			continue
		}

		item := items[i].([]interface{})
		popupItem.setItem(item, selected == i)

		var menuWidth int
		menuWidth, height = popupItem.menu.getSize()
		kindWidth, height = popupItem.kind.getSize()

		if menuWidth > menuWidthMax {
			menuWidthMax = menuWidth
		}
		y := heightSum
		heightSum += height
		ui.QueueMain(func() {
			popupItem.kind.span.SetPosition(0, y)
			popupItem.menu.span.SetPosition(kindWidth, y)
		})
	}

	for i = 0; i < p.total; i++ {
		if i >= len(items) {
			continue
		}
		popupItem := popupItems[i]
		ui.QueueMain(func() {
			popupItem.kind.span.SetSize(kindWidth, height)
			popupItem.kind.span.Show()
			popupItem.kind.span.QueueRedrawAll()
			popupItem.menu.span.SetSize(menuWidthMax, height)
			popupItem.menu.span.Show()
			popupItem.menu.span.QueueRedrawAll()
		})
	}

	ui.QueueMain(func() {
		p.box.SetPosition(
			col*editor.font.width-kindWidth-p.items[0].menu.paddingLeft,
			(row+1)*editor.font.lineHeight,
		)
		p.box.SetSize(menuWidthMax+kindWidth, heightSum)
		p.box.Show()
	})
}

func (p *PopupMenu) hide(args []interface{}) {
	p.hidden = true

	time.AfterFunc(50*time.Millisecond, func() {
		if p.hidden {
			ui.QueueMain(func() {
				p.box.Hide()
			})
		}
	})
}

func (p *PopupMenu) selectItem(args []interface{}) {
	selected := reflectToInt(args[0].([]interface{})[0])
	for i := 0; i < p.total; i++ {
		popupItem := p.items[i]
		if selected == i {
			popupItem.menu.SetBackground(newRGBA(81, 154, 186, 1))
			ui.QueueMain(func() {
				popupItem.menu.span.QueueRedrawAll()
			})
		} else {
			popupItem.menu.SetBackground(newRGBA(14, 17, 18, 1))
			ui.QueueMain(func() {
				popupItem.menu.span.QueueRedrawAll()
			})
		}
	}
}

func (p *PopupItem) setItem(item []interface{}, selected bool) {
	text := item[0].(string)
	kindText := item[1].(string)
	p.setKind(kindText, selected)

	fg := newRGBA(205, 211, 222, 1)
	p.menu.SetColor(fg)
	if selected {
		p.menu.SetBackground(newRGBA(81, 154, 186, 1))
	} else {
		p.menu.SetBackground(newRGBA(14, 17, 18, 1))
	}
	p.menu.SetFont(editor.font.font)
	p.menu.SetText(text)

	p.menu.paddingLeft = 10
	p.menu.paddingRight = 10
	p.menu.paddingTop = 8
	p.menu.paddingBottom = 8

	p.kind.paddingLeft = 10
	p.kind.paddingRight = 10
	p.kind.paddingTop = 8
	p.kind.paddingBottom = 8
}

func (p *PopupItem) setKind(kindText string, selected bool) {
	color := newRGBA(151, 195, 120, 1)
	bg := newRGBA(151, 195, 120, 0.2)

	switch kindText {
	case "function", "func":
		kindText = "f"
		color = newRGBA(97, 174, 239, 1)
		bg = newRGBA(97, 174, 239, 0.2)
	case "var", "statement", "instance", "param", "import":
		kindText = "v"
		color = newRGBA(223, 106, 115, 1)
		bg = newRGBA(223, 106, 115, 0.2)
	case "const":
		kindText = "c"
		color = newRGBA(223, 106, 115, 1)
		bg = newRGBA(223, 106, 115, 0.2)
	case "class":
		kindText = "c"
		color = newRGBA(229, 193, 124, 1)
		bg = newRGBA(229, 193, 124, 0.2)
	case "type":
		kindText = "t"
		color = newRGBA(229, 193, 124, 1)
		bg = newRGBA(229, 193, 124, 0.2)
	case "module":
		kindText = "m"
		color = newRGBA(42, 161, 152, 1)
		bg = newRGBA(42, 161, 152, 0.2)
	case "keyword":
		kindText = "k"
		color = newRGBA(42, 161, 152, 1)
		bg = newRGBA(42, 161, 152, 0.2)
	case "package":
		kindText = "p"
		color = newRGBA(42, 161, 152, 1)
		bg = newRGBA(42, 161, 152, 0.2)
	default:
		kindText = "b"
	}
	p.kind.SetColor(color)
	p.kind.SetBackground(bg)
	p.kind.SetFont(editor.font.font)
	p.kind.SetText(kindText)
}

func (p *PopupItem) hide() {
	ui.QueueMain(func() {
		p.kind.span.Hide()
		p.menu.span.Hide()
	})
}
<|endoftext|>


<commit_before>// Package tint implements a single function to tint an image with a specified
// colour.
package tint

import (
	"github.com/hawx/img/blend"
	"image"
	"image/color"
)

func Tint(img image.Image, with color.Color) image.Image {
	blendLayer := image.NewUniform(with)
	return blend.Normal(img, blendLayer)
}
<commit_msg>tint seems to look better with --linear-light<commit_after>// Package tint implements a single function to tint an image with a specified
// colour.
package tint

import (
	"github.com/hawx/img/blend"
	"image"
	"image/color"
)

func Tint(img image.Image, with color.Color) image.Image {
	blendLayer := image.NewUniform(with)
	return blend.LinearLight(img, blendLayer)
}
<|endoftext|>


<commit_before>package postailer

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
)

type readSeekCloser interface {
	io.ReadCloser
	io.Seeker
}

// Postailer is main struct of postailer package
type Postailer struct {
	filePath string
	posFile  string

	pos     *position
	oldfile bool
	file    readSeekCloser
}

type position struct {
	Inode uint  `json:"inode"`
	Pos   int64 `json:"pos"`
}

// Open the file with posfile
func Open(filepath, posfile string) (*Postailer, error) {
	pt := &Postailer{
		filePath: filepath,
		posFile:  posfile,
	}
	err := pt.open()
	if err != nil {
		return nil, err
	}
	return pt, nil
}

func loadPos(fname string) (*position, error) {
	pos := &position{}
	_, err := os.Stat(fname)
	if err == nil { // posfile exists
		b, err := ioutil.ReadFile(fname)
		if err == nil {
			err = json.Unmarshal(b, pos)
		}
		return pos, err
	}
	return pos, nil
}

var errFileNotFoundByInode = fmt.Errorf("old file not found")

func (pt *Postailer) open() error {
	pt.pos, _ = loadPos(pt.posFile)
	fi, err := os.Stat(pt.filePath)
	// XXX may be missing the file for a moment while rotating...
	if err != nil {
		return err
	}
	inode := detectInode(fi)
	if pt.pos.Inode > 0 && inode != pt.pos.Inode {
		if oldFile, err := findFileByInode(pt.pos.Inode, filepath.Dir(pt.filePath)); err == nil {
			oldf, err := os.Open(oldFile)
			if err != nil {
				return err
			}
			oldfi, _ := oldf.Stat()
			if oldfi.Size() > pt.pos.Pos {
				oldf.Seek(pt.pos.Pos, io.SeekStart)
				pt.oldfile = true
				pt.file = oldf
				return nil
			}
		} else if err != errFileNotFoundByInode {
			return err
		}
		pt.pos.Pos = 0
	}
	pt.pos.Inode = inode
	f, err := os.Open(pt.filePath)
	if err != nil {
		return err
	}
	if pt.pos.Pos < fi.Size() {
		f.Seek(pt.pos.Pos, io.SeekStart)
	} else {
		pt.pos.Pos = 0
	}
	pt.file = f
	return nil
}

// Read for io.Reader interface
func (pt *Postailer) Read(p []byte) (int, error) {
	n, err := pt.file.Read(p)
	pt.pos.Pos += int64(n)
	if !(pt.oldfile && ((err == nil && n < len(p)) || (err == io.EOF))) {
		return n, err
	}
	pt.file.Close()
	f, err := os.Open(pt.filePath)
	if err != nil {
		return n, err
	}
	fi, err := f.Stat()
	if err != nil {
		return n, err
	}
	pt.pos = &position{Inode: detectInode(fi)}
	pt.oldfile = false
	pt.file = f

	if n == len(p) {
		return n, err
	}
	buf := make([]byte, len(p)-n)
	nn, err := pt.file.Read(buf)
	for i := 0; i < nn; i++ {
		p[n+i] = buf[i]
	}
	pt.pos.Pos = int64(nn)
	return n + nn, err
}

// Seek for io.Seeker interface
func (pt *Postailer) Seek(offset int64, whence int) (int64, error) {
	ret, err := pt.file.Seek(offset, whence)
	if err == nil {
		pt.pos.Pos = ret
	}
	return ret, err
}

// Close for io.Closer interface
func (pt *Postailer) Close() error {
	defer pt.file.Close()
	return savePos(pt.posFile, pt.pos)
}

func savePos(posfile string, pos *position) error {
	b, _ := json.Marshal(pos)
	if err := os.MkdirAll(filepath.Dir(posfile), 0755); err != nil {
		return nil
	}
	return writeFileAtomically(posfile, b)
}

func findFileByInode(inode uint, dir string) (string, error) {
	fis, err := ioutil.ReadDir(dir)
	if err != nil {
		return "", err
	}
	for _, fi := range fis {
		if detectInode(fi) == inode {
			return filepath.Join(dir, fi.Name()), nil
		}
	}
	return "", errFileNotFoundByInode
}

func writeFileAtomically(f string, contents []byte) error {
	// MUST be located on same disk partition
	tmpf, err := ioutil.TempFile(filepath.Dir(f), "tmp")
	if err != nil {
		return err
	}
	// os.Remove here works successfully when tmpf.Write fails or os.Rename fails.
	// In successful case, os.Remove fails because the temporary file is already renamed.
	defer os.Remove(tmpf.Name())
	_, err = tmpf.Write(contents)
	tmpf.Close() // should be called before rename
	if err != nil {
		return err
	}
	return os.Rename(tmpf.Name(), f)
}
<commit_msg>use copy<commit_after>package postailer

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
)

type readSeekCloser interface {
	io.ReadCloser
	io.Seeker
}

// Postailer is main struct of postailer package
type Postailer struct {
	filePath string
	posFile  string

	pos     *position
	oldfile bool
	file    readSeekCloser
}

type position struct {
	Inode uint  `json:"inode"`
	Pos   int64 `json:"pos"`
}

// Open the file with posfile
func Open(filepath, posfile string) (*Postailer, error) {
	pt := &Postailer{
		filePath: filepath,
		posFile:  posfile,
	}
	err := pt.open()
	if err != nil {
		return nil, err
	}
	return pt, nil
}

func loadPos(fname string) (*position, error) {
	pos := &position{}
	_, err := os.Stat(fname)
	if err == nil { // posfile exists
		b, err := ioutil.ReadFile(fname)
		if err == nil {
			err = json.Unmarshal(b, pos)
		}
		return pos, err
	}
	return pos, nil
}

var errFileNotFoundByInode = fmt.Errorf("old file not found")

func (pt *Postailer) open() error {
	pt.pos, _ = loadPos(pt.posFile)
	fi, err := os.Stat(pt.filePath)
	// XXX may be missing the file for a moment while rotating...
	if err != nil {
		return err
	}
	inode := detectInode(fi)
	if pt.pos.Inode > 0 && inode != pt.pos.Inode {
		if oldFile, err := findFileByInode(pt.pos.Inode, filepath.Dir(pt.filePath)); err == nil {
			oldf, err := os.Open(oldFile)
			if err != nil {
				return err
			}
			oldfi, _ := oldf.Stat()
			if oldfi.Size() > pt.pos.Pos {
				oldf.Seek(pt.pos.Pos, io.SeekStart)
				pt.oldfile = true
				pt.file = oldf
				return nil
			}
		} else if err != errFileNotFoundByInode {
			return err
		}
		pt.pos.Pos = 0
	}
	pt.pos.Inode = inode
	f, err := os.Open(pt.filePath)
	if err != nil {
		return err
	}
	if pt.pos.Pos < fi.Size() {
		f.Seek(pt.pos.Pos, io.SeekStart)
	} else {
		pt.pos.Pos = 0
	}
	pt.file = f
	return nil
}

// Read for io.Reader interface
func (pt *Postailer) Read(p []byte) (int, error) {
	n, err := pt.file.Read(p)
	pt.pos.Pos += int64(n)
	if !(pt.oldfile && ((err == nil && n < len(p)) || (err == io.EOF))) {
		return n, err
	}
	pt.file.Close()
	f, err := os.Open(pt.filePath)
	if err != nil {
		return n, err
	}
	fi, err := f.Stat()
	if err != nil {
		return n, err
	}
	pt.pos = &position{Inode: detectInode(fi)}
	pt.oldfile = false
	pt.file = f

	if n == len(p) {
		return n, err
	}
	buf := make([]byte, len(p)-n)
	nn, err := pt.file.Read(buf)
	copy(p[n:n+nn], buf[0:nn])
	pt.pos.Pos = int64(nn)
	return n + nn, err
}

// Seek for io.Seeker interface
func (pt *Postailer) Seek(offset int64, whence int) (int64, error) {
	ret, err := pt.file.Seek(offset, whence)
	if err == nil {
		pt.pos.Pos = ret
	}
	return ret, err
}

// Close for io.Closer interface
func (pt *Postailer) Close() error {
	defer pt.file.Close()
	return savePos(pt.posFile, pt.pos)
}

func savePos(posfile string, pos *position) error {
	b, _ := json.Marshal(pos)
	if err := os.MkdirAll(filepath.Dir(posfile), 0755); err != nil {
		return nil
	}
	return writeFileAtomically(posfile, b)
}

func findFileByInode(inode uint, dir string) (string, error) {
	fis, err := ioutil.ReadDir(dir)
	if err != nil {
		return "", err
	}
	for _, fi := range fis {
		if detectInode(fi) == inode {
			return filepath.Join(dir, fi.Name()), nil
		}
	}
	return "", errFileNotFoundByInode
}

func writeFileAtomically(f string, contents []byte) error {
	// MUST be located on same disk partition
	tmpf, err := ioutil.TempFile(filepath.Dir(f), "tmp")
	if err != nil {
		return err
	}
	// os.Remove here works successfully when tmpf.Write fails or os.Rename fails.
	// In successful case, os.Remove fails because the temporary file is already renamed.
	defer os.Remove(tmpf.Name())
	_, err = tmpf.Write(contents)
	tmpf.Close() // should be called before rename
	if err != nil {
		return err
	}
	return os.Rename(tmpf.Name(), f)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strconv"
	"sync"
	"time"
)

var host = "localhost:8080"

func main() {
	// grab the start time so we can time our operation
	start := time.Now()

	// open the file, log the error and panic if we have one
	input, err := os.Open("./cats.json")
	if err != nil {
		log.Fatal(err)
	}

	// do the work!
	avg := calcAverageWeight(input)

	log.Print("the average weight is ", avg)
	log.Print("work complete in ", time.Since(start))
}

// calcAverageWeight read from an io.ReaderCloser containing Cats and make a request for each line
func calcAverageWeight(file io.ReadCloser) float32 {
	// set up our func to close the file as soon as it completes (just in case)
	defer file.Close()

	// create a buffered channel to move data from the file to our goroutines
	cats := make(chan []byte, 10000)
	// create a buffered channel to gather the results
	weights := make(chan int64, 1000)
	// create a var to hold our average
	var avg float32

	// create a WaitGroup to help us keep track of our goroutines
	var weighers sync.WaitGroup
	for i := 0; i < 10; i++ {
		// increment the waitgroup to register our new goroutine
		weighers.Add(1)
		// kick off a bounce checker in a goroutine!
		go catWeigher(cats, weights, &weighers)
	}

	// create a goroutine to gather the weights for an average
	// use a simple chan to mark complete  bc it's only 1 goroutine
	done := make(chan bool)
	go func() {
		var catCount int64
		var totalWeight int64
		for weight := range weights {
			catCount++
			totalWeight += weight
		}

		avg = float32(totalWeight) / float32(catCount)

		// alert the main thread we're done
		done <- true
	}()

	// scan each line out of our file and toss it on a buffered channel
	go func() {
		// create a new scanner to help us iterate over each line
		s := bufio.NewScanner(file)
		for s.Scan() {
			// allocate bytes into fresh slice to preserve order
			catBytes := append([]byte{}, s.Bytes()...)
			cats <- catBytes
		}

		// close the channel to alert our workers there is no more to read
		close(cats)

		// check for any errors in the scanner after iterating
		if err := s.Err(); err != nil {
			log.Print("scanner error: ", err)
		}

		// close our input file at the end
		file.Close()
	}()

	// wait for the goroutine pool to finish their work and return
	weighers.Wait()
	// tell the output reader that there are no more records to register
	close(weights)
	// wait for result reader to complete.
	<-done
	return avg
}

func catWeigher(cats chan []byte, weights chan int64, wg *sync.WaitGroup) {
	// set the func up to mark itself as done as soon as it completes
	defer wg.Done()

	// iterate over each line passed along through the channel
	for catBytes := range cats {
		// get the cats weight. log and continue on error
		weight, err := getWeight(host, catBytes)
		if err != nil {
			log.Print(err)
			continue
		}
		// pass the weight along to the output channel
		weights <- weight
	}
}

func getWeight(host string, catBytes []byte) (int64, error) {
	// post against our isbounce service with the line as the body
	resp, err := http.Post(fmt.Sprintf("http://%s/catweight", host), "application/json", bytes.NewReader(catBytes))
	if err != nil {
		return 0, err
	}

	// create a var and read from the response body into it
	var weight []byte
	weight, err = ioutil.ReadAll(resp.Body)
	if err != nil {
		return 0, err
	}
	resp.Body.Close()

	// parse the response into an int
	return strconv.ParseInt(string(weight), 10, 64)
}
<commit_msg>added tests for tool<commit_after>package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strconv"
	"sync"
	"time"
)

var host = "http://localhost:8080"

func main() {
	// grab the start time so we can time our operation
	start := time.Now()

	// open the file, log the error and panic if we have one
	input, err := os.Open("./cats.json")
	if err != nil {
		log.Fatal(err)
	}
	defer input.Close()

	// do the work!
	avg := calcAverageWeight(input)

	log.Print("the average weight is ", avg)
	log.Print("work complete in ", time.Since(start))
}

var procs = 10

// calcAverageWeight read from an io.ReaderCloser containing Cats and make a request for each line
func calcAverageWeight(file io.Reader) float32 {

	// create a buffered channel to move data from the file to our goroutines
	cats := make(chan []byte, 10000)
	// create a buffered channel to gather the results
	weights := make(chan int64, 1000)
	// create a var to hold our average
	var avg float32

	// create a WaitGroup to help us keep track of our goroutines
	var weighers sync.WaitGroup
	for i := 0; i < procs; i++ {
		// increment the waitgroup to register our new goroutine
		weighers.Add(1)
		// kick off a bounce checker in a goroutine!
		go catWeigher(cats, weights, &weighers)
	}

	// create a goroutine to gather the weights for an average
	// use a simple chan to mark complete  bc it's only 1 goroutine
	done := make(chan bool)
	go func() {
		var catCount int64
		var totalWeight int64
		for weight := range weights {
			catCount++
			totalWeight += weight
		}

		avg = float32(totalWeight) / float32(catCount)

		// alert the main thread we're done
		done <- true
	}()

	// scan each line out of our file and toss it on a buffered channel
	go func() {
		// create a new scanner to help us iterate over each line
		s := bufio.NewScanner(file)
		for s.Scan() {
			// allocate bytes into fresh slice to preserve order
			catBytes := append([]byte{}, s.Bytes()...)
			cats <- catBytes
		}

		// close the channel to alert our workers there is no more to read
		close(cats)

		// check for any errors in the scanner after iterating
		if err := s.Err(); err != nil {
			log.Print("scanner error: ", err)
		}
	}()

	// wait for the goroutine pool to finish their work and return
	weighers.Wait()
	// tell the output reader that there are no more records to register
	close(weights)
	// wait for result reader to complete.
	<-done
	return avg
}

func catWeigher(cats chan []byte, weights chan int64, wg *sync.WaitGroup) {
	// set the func up to mark itself as done as soon as it completes
	defer wg.Done()

	// iterate over each line passed along through the channel
	for catBytes := range cats {
		// get the cats weight. log and continue on error
		weight, err := getWeight(host, catBytes)
		if err != nil {
			log.Print(err)
			continue
		}
		// pass the weight along to the output channel
		weights <- weight
	}
}

func getWeight(host string, catBytes []byte) (int64, error) {
	// post against our isbounce service with the line as the body
	resp, err := http.Post(fmt.Sprintf("%s/catweight", host), "application/json", bytes.NewReader(catBytes))
	if err != nil {
		return 0, err
	}

	// create a var and read from the response body into it
	var weight []byte
	weight, err = ioutil.ReadAll(resp.Body)
	if err != nil {
		return 0, err
	}
	resp.Body.Close()

	// parse the response into an int
	return strconv.ParseInt(string(weight), 10, 64)
}
<|endoftext|>


<commit_before>// Copyright 2014 Google Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to writing, software distributed
// under the License is distributed on a "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.

// tree is a very simple implementation of the tree unix command.
// This implementation doesn't provide any options as flags.
package main

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"sort"
	"strings"
)

type caseInsensitive struct {
	values []string
}

func (ci caseInsensitive) Len() int {
	return len(ci.values)
}

func (ci caseInsensitive) Less(i, j int) bool {
	return strings.ToLower(ci.values[i]) < strings.ToLower(ci.values[j])
}

func (ci caseInsensitive) Swap(i, j int) {
	ci.values[i], ci.values[j] = ci.values[j], ci.values[i]
}

func main() {
	path := "."
	if len(os.Args) > 1 {
		path = os.Args[1]
	}
	path, err := filepath.Abs(path)
	if err != nil {
		log.Fatalf("absolute %s: %v", path, err)
	}
	dirs, files, err := visit(path, "")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("\n%v directories, %v files\n", dirs, files)
}

func visit(path, indent string) (dirs, files int, err error) {
	fi, err := os.Stat(path)
	if err != nil {
		return 0, 0, fmt.Errorf("stat %s: %v", path, err)
	}
	fmt.Println(fi.Name())
	if !fi.IsDir() {
		return 0, 1, nil
	}

	dir, err := os.Open(path)
	if err != nil {
		return 1, 0, fmt.Errorf("open %s: %v", path, err)
	}
	names, err := dir.Readdirnames(-1)
	dir.Close()
	if err != nil {
		return 1, 0, fmt.Errorf("read dir names %s: %v", path, err)
	}
	names = removeHidden(names)
	sort.Sort(caseInsensitive{names})
	add := "│   "
	for i, name := range names {
		if i == len(names)-1 {
			fmt.Printf(indent + "└── ")
			add = "    "
		} else {
			fmt.Printf(indent + "├── ")
		}
		d, f, err := visit(filepath.Join(path, name), indent+add)
		if err != nil {
			log.Println(err)
		}
		dirs, files = dirs+d, files+f
	}
	return dirs + 1, files, nil
}

func removeHidden(files []string) []string {
	clean := []string{}
	for _, f := range files {
		if strings.HasPrefix(f, ".") {
			continue
		}
		clean = append(clean, f)
	}
	return clean
}
<commit_msg>review changes<commit_after>// Copyright 2014 Google Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to writing, software distributed
// under the License is distributed on a "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.

// tree is a very simple implementation of the tree unix command.
// This implementation doesn't provide any options as flags.
package main

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"sort"
	"strings"
)

type caseInsensitive struct {
	values []string
}

func (ci caseInsensitive) Len() int {
	return len(ci.values)
}

func (ci caseInsensitive) Less(i, j int) bool {
	return strings.ToLower(ci.values[i]) < strings.ToLower(ci.values[j])
}

func (ci caseInsensitive) Swap(i, j int) {
	ci.values[i], ci.values[j] = ci.values[j], ci.values[i]
}

func main() {
	path := "."
	if len(os.Args) > 1 {
		path = os.Args[1]
	}
	path, err := filepath.Abs(path)
	if err != nil {
		log.Fatalf("absolute %s: %v", path, err)
	}
	dirs, files, err := visit(path, "")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("\n%v directories, %v files\n", dirs, files)
}

func visit(path, indent string) (dirs, files int, err error) {
	fi, err := os.Stat(path)
	if err != nil {
		return 0, 0, fmt.Errorf("stat %s: %v", path, err)
	}
	fmt.Println(fi.Name())
	if !fi.IsDir() {
		return 0, 1, nil
	}

	dir, err := os.Open(path)
	if err != nil {
		return 1, 0, fmt.Errorf("open %s: %v", path, err)
	}
	names, err := dir.Readdirnames(-1)
	dir.Close()
	if err != nil {
		return 1, 0, fmt.Errorf("read dir names %s: %v", path, err)
	}
	names = removeHidden(names)
	sort.Sort(caseInsensitive{names})
	add := "│   "
	for i, name := range names {
		if i == len(names)-1 {
			fmt.Printf(indent + "└── ")
			add = "    "
		} else {
			fmt.Printf(indent + "├── ")
		}
		d, f, err := visit(filepath.Join(path, name), indent+add)
		if err != nil {
			log.Println(err)
		}
		dirs, files = dirs+d, files+f
	}
	return dirs + 1, files, nil
}

func removeHidden(files []string) []string {
	var clean []string
	for _, f := range files {
		if f[0] != '.' {
			clean = append(clean, f)
		}
	}
	return clean
}
<|endoftext|>


<commit_before>package trie

// Trie is a radix tree.
type Trie struct {
	name     byte
	terminal bool
	children []*Trie
}

func (t *Trie) getNode(c byte) *Trie {
	for _, n := range t.children {
		if n.name == c {
			return n
		}
	}
	return nil
}

func (t *Trie) addChar(c byte) *Trie {
	n := t.getNode(c)
	if n == nil {
		n = &Trie{name: c}
		t.children = append(t.children, n)
	}
	return n
}

// Add adds the string to the trie.
func (t *Trie) Add(s string) {
	if len(s) == 0 {
		t.terminal = true
		return
	}
	n := t.addChar(s[0])
	n.Add(s[1:])
}

// HasPrefix returns whether any entry in the trie has s as its prefix.
func (t *Trie) HasPrefix(s string) bool {
	if len(s) == 0 {
		return true
	}
	n := t.getNode(s[0])
	if n == nil {
		return false
	}
	return n.HasPrefix(s[1:])
}

// HasString returns whether the given string is in the trie as a
// complete entry.
func (t *Trie) HasString(s string) bool {
	if len(s) == 0 && t.terminal {
		return true
	}
	if len(s) == 0 {
		return false
	}
	n := t.getNode(s[0])
	if n == nil {
		return false
	}
	return n.HasString(s[1:])
}

func (t *Trie) substrings() []string {
	var strs []string
	for _, n := range t.children {
		for _, sstr := range n.Substrings() {
			strs = append(strs, string(t.name)+sstr)
		}
	}
	if t.terminal {
		strs = append(strs, string(t.name))
	}
	return strs
}

func (t *Trie) subtrie(s string) *Trie {
	n := t
	for i := 0; i < len(s); i++ {
		n = n.getNode(s[i])
		if n == nil {
			return nil
		}
	}
	return n
}

// WithPrefix returns all entries in the trie that begin with the
// given prefix.
func (t *Trie) WithPrefix(s string) []string {
	if len(s) == 0 {
		return t.substrings()
	}
	n := t.subtrie(s)
	var strs []string
	for _, str := range n.Substrings() {
		strs = append(strs, s[:len(s)-1]+str)
	}
	return strs
}
<commit_msg>Maybe run tests before you commit.<commit_after>package trie

// Trie is a radix tree.
type Trie struct {
	name     byte
	terminal bool
	children []*Trie
}

func (t *Trie) getNode(c byte) *Trie {
	for _, n := range t.children {
		if n.name == c {
			return n
		}
	}
	return nil
}

func (t *Trie) addChar(c byte) *Trie {
	n := t.getNode(c)
	if n == nil {
		n = &Trie{name: c}
		t.children = append(t.children, n)
	}
	return n
}

// Add adds the string to the trie.
func (t *Trie) Add(s string) {
	if len(s) == 0 {
		t.terminal = true
		return
	}
	n := t.addChar(s[0])
	n.Add(s[1:])
}

// HasPrefix returns whether any entry in the trie has s as its prefix.
func (t *Trie) HasPrefix(s string) bool {
	if len(s) == 0 {
		return true
	}
	n := t.getNode(s[0])
	if n == nil {
		return false
	}
	return n.HasPrefix(s[1:])
}

// HasString returns whether the given string is in the trie as a
// complete entry.
func (t *Trie) HasString(s string) bool {
	if len(s) == 0 && t.terminal {
		return true
	}
	if len(s) == 0 {
		return false
	}
	n := t.getNode(s[0])
	if n == nil {
		return false
	}
	return n.HasString(s[1:])
}

func (t *Trie) substrings() []string {
	var strs []string
	for _, n := range t.children {
		for _, sstr := range n.substrings() {
			strs = append(strs, string(t.name)+sstr)
		}
	}
	if t.terminal {
		strs = append(strs, string(t.name))
	}
	return strs
}

func (t *Trie) subtrie(s string) *Trie {
	n := t
	for i := 0; i < len(s); i++ {
		n = n.getNode(s[i])
		if n == nil {
			return nil
		}
	}
	return n
}

// WithPrefix returns all entries in the trie that begin with the
// given prefix.
func (t *Trie) WithPrefix(s string) []string {
	if len(s) == 0 {
		return t.substrings()
	}
	n := t.subtrie(s)
	var strs []string
	for _, str := range n.substrings() {
		strs = append(strs, s[:len(s)-1]+str)
	}
	return strs
}
<|endoftext|>


<commit_before>package blink

// +build linux
// #cgo pkg-config: libusb-1.0
// #cgo LDFLAGS: -lusb-1.0
// #include <libusb-1.0/libusb.h>
import "C"

import (
	"errors"
	"fmt"
	"reflect"
	"strings"
	"unsafe"
)

const (
	hidRequestTypeClass   = (0x01 << 5)
	hidRecipientInterface = 0x01
	hidEndpointOut        = 0x00
	hidSetReport          = 0x09
)

func init() {
	C.libusb_init(nil)
}

type usbDeviceInfo struct {
	path                string
	vendorId, productId uint16
}

type usbDevice struct {
	handle *C.libusb_device_handle
	info   usbDeviceInfo
}

// pretty much based on github.com/boombuler/hid
// https://github.com/boombuler/hid/blob/08a7959390cac69dfd373882ac0a4435765a2545/hid_linux.go#L26
func usbDevices() <-chan usbDeviceInfo {
	result := make(chan usbDeviceInfo)
	go func() {
		var devices **C.struct_libusb_device
		count := C.libusb_get_device_list(nil, &devices)
		if count < 0 {
			close(result)
			return
		}
		defer C.libusb_free_device_list(devices, 1)

		for _, dev := range slice(devices, count) {
			di, err := readDeviceInfo(dev)
			if err != nil {
				continue
			}
			result <- di
		}

		close(result)
	}()

	return result
}

// pretty much based on github.com/boombuler/hid
// https://github.com/boombuler/hid/blob/08a7959390cac69dfd373882ac0a4435765a2545/hid_linux.go#L58
func (di usbDeviceInfo) open() (*usbDevice, error) {
	var devices **C.struct_libusb_device
	cnt := C.libusb_get_device_list(nil, &devices)
	if cnt < 0 {
		return nil, fmt.Errorf("could not open usb device with path %q: could not list USB devices", di.path)
	}
	defer C.libusb_free_device_list(devices, 1)

	for _, dev := range slice(devices, cnt) {
		candidate, err := readDeviceInfo(dev)
		if err != nil {
			continue
		}
		if di.path == candidate.path {
			var handle *C.libusb_device_handle
			err := C.libusb_open(dev, &handle)
			if err != 0 {
				return nil, usbError(err)
			}
			dev := &usbDevice{
				info:   candidate,
				handle: handle,
			}
			return dev, nil
		}
	}

	return nil, errors.New("couldn't open USB device")
}

func readDeviceInfo(dev *C.libusb_device) (di usbDeviceInfo, err error) {
	var desc C.struct_libusb_device_descriptor
	if result := C.libusb_get_device_descriptor(dev, &desc); result < 0 {
		return di, usbError(result)
	}

	numbers, err := getPortNumbers(dev)
	if err != nil {
		return di, err
	}

	return usbDeviceInfo{
		path:      fmt.Sprintf("%.4x:%.4x:%s", desc.idVendor, desc.idProduct, numbers),
		vendorId:  uint16(desc.idVendor),
		productId: uint16(desc.idProduct),
	}, nil
}

// entirely based on github.com/boombuler/hid
// https://github.com/boombuler/hid/blob/08a7959390cac69dfd373882ac0a4435765a2545/hid_linux.go#L237
func getPortNumbers(dev *C.libusb_device) (string, error) {
	const maxlen = 7 // As per the USB 3.0 specs, the current maximum limit for the depth is 7
	var numarr [maxlen]C.uint8_t
	len := C.libusb_get_port_numbers(dev, &numarr[0], maxlen)
	if len < 0 || len > maxlen {
		return "", usbError(len)
	}

	var numstr []string = make([]string, len)
	for i := 0; i < int(len); i++ {
		numstr[i] = fmt.Sprintf("%.2x", numarr[i])
	}

	return strings.Join(numstr, "."), nil
}

// entirely based on github.com/boombuler/hid
// https://github.com/boombuler/hid/blob/08a7959390cac69dfd373882ac0a4435765a2545/hid_linux.go#L251
func slice(devices **C.struct_libusb_device, cnt C.ssize_t) []*C.libusb_device {
	var slice []*C.libusb_device
	*(*reflect.SliceHeader)(unsafe.Pointer(&slice)) = reflect.SliceHeader{
		Data: uintptr(unsafe.Pointer(devices)),
		Len:  int(cnt),
		Cap:  int(cnt),
	}
	return slice
}

func (d *usbDevice) write(c command) error {
	if d.handle == nil {
		return errors.New("usb device has not been opend")
	}

	const reportId = 1
	const index = 0
	const timeout = 5000

	data := c.bytes()
	n := len(data)
	written := C.libusb_control_transfer(d.handle,
		C.uint8_t(hidEndpointOut|hidRecipientInterface|hidRequestTypeClass),
		C.uint8_t(hidSetReport),
		C.uint16_t(reportId),
		C.uint16_t(index),
		(*C.uchar)(&data[0]),
		C.uint16_t(n),
		C.uint(timeout),
	)

	if int(written) == n {
		return nil
	}

	return usbError(written)
}

func (d *usbDevice) close() {
	if d == nil || d.handle == nil {
		return
	}

	C.libusb_close(d.handle)
	d.handle = nil
}

type usbError C.int

func (e usbError) Error() string {
	return fmt.Sprintf("libusb: %s [code %d]", usbErrorString[e], int(e))
}

var usbErrorString = map[usbError]string{
	C.LIBUSB_SUCCESS:             "success",
	C.LIBUSB_ERROR_IO:            "i/o error",
	C.LIBUSB_ERROR_INVALID_PARAM: "invalid param",
	C.LIBUSB_ERROR_ACCESS:        "bad access",
	C.LIBUSB_ERROR_NO_DEVICE:     "no device",
	C.LIBUSB_ERROR_NOT_FOUND:     "not found",
	C.LIBUSB_ERROR_BUSY:          "device or resource busy",
	C.LIBUSB_ERROR_TIMEOUT:       "timeout",
	C.LIBUSB_ERROR_OVERFLOW:      "overflow",
	C.LIBUSB_ERROR_PIPE:          "pipe error",
	C.LIBUSB_ERROR_INTERRUPTED:   "interrupted",
	C.LIBUSB_ERROR_NO_MEM:        "out of memory",
	C.LIBUSB_ERROR_NOT_SUPPORTED: "not supported",
	C.LIBUSB_ERROR_OTHER:         "unknown error",
}
<commit_msg>Fix build tag<commit_after>// +build linux
package blink

// #cgo pkg-config: libusb-1.0
// #cgo LDFLAGS: -lusb-1.0
// #include <libusb-1.0/libusb.h>
import "C"

import (
	"errors"
	"fmt"
	"reflect"
	"strings"
	"unsafe"
)

const (
	hidRequestTypeClass   = (0x01 << 5)
	hidRecipientInterface = 0x01
	hidEndpointOut        = 0x00
	hidSetReport          = 0x09
)

func init() {
	C.libusb_init(nil)
}

type usbDeviceInfo struct {
	path                string
	vendorId, productId uint16
}

type usbDevice struct {
	handle *C.libusb_device_handle
	info   usbDeviceInfo
}

// pretty much based on github.com/boombuler/hid
// https://github.com/boombuler/hid/blob/08a7959390cac69dfd373882ac0a4435765a2545/hid_linux.go#L26
func usbDevices() <-chan usbDeviceInfo {
	result := make(chan usbDeviceInfo)
	go func() {
		var devices **C.struct_libusb_device
		count := C.libusb_get_device_list(nil, &devices)
		if count < 0 {
			close(result)
			return
		}
		defer C.libusb_free_device_list(devices, 1)

		for _, dev := range slice(devices, count) {
			di, err := readDeviceInfo(dev)
			if err != nil {
				continue
			}
			result <- di
		}

		close(result)
	}()

	return result
}

// pretty much based on github.com/boombuler/hid
// https://github.com/boombuler/hid/blob/08a7959390cac69dfd373882ac0a4435765a2545/hid_linux.go#L58
func (di usbDeviceInfo) open() (*usbDevice, error) {
	var devices **C.struct_libusb_device
	cnt := C.libusb_get_device_list(nil, &devices)
	if cnt < 0 {
		return nil, fmt.Errorf("could not open usb device with path %q: could not list USB devices", di.path)
	}
	defer C.libusb_free_device_list(devices, 1)

	for _, dev := range slice(devices, cnt) {
		candidate, err := readDeviceInfo(dev)
		if err != nil {
			continue
		}
		if di.path == candidate.path {
			var handle *C.libusb_device_handle
			err := C.libusb_open(dev, &handle)
			if err != 0 {
				return nil, usbError(err)
			}
			dev := &usbDevice{
				info:   candidate,
				handle: handle,
			}
			return dev, nil
		}
	}

	return nil, errors.New("couldn't open USB device")
}

func readDeviceInfo(dev *C.libusb_device) (di usbDeviceInfo, err error) {
	var desc C.struct_libusb_device_descriptor
	if result := C.libusb_get_device_descriptor(dev, &desc); result < 0 {
		return di, usbError(result)
	}

	numbers, err := getPortNumbers(dev)
	if err != nil {
		return di, err
	}

	return usbDeviceInfo{
		path:      fmt.Sprintf("%.4x:%.4x:%s", desc.idVendor, desc.idProduct, numbers),
		vendorId:  uint16(desc.idVendor),
		productId: uint16(desc.idProduct),
	}, nil
}

// entirely based on github.com/boombuler/hid
// https://github.com/boombuler/hid/blob/08a7959390cac69dfd373882ac0a4435765a2545/hid_linux.go#L237
func getPortNumbers(dev *C.libusb_device) (string, error) {
	const maxlen = 7 // As per the USB 3.0 specs, the current maximum limit for the depth is 7
	var numarr [maxlen]C.uint8_t
	len := C.libusb_get_port_numbers(dev, &numarr[0], maxlen)
	if len < 0 || len > maxlen {
		return "", usbError(len)
	}

	var numstr []string = make([]string, len)
	for i := 0; i < int(len); i++ {
		numstr[i] = fmt.Sprintf("%.2x", numarr[i])
	}

	return strings.Join(numstr, "."), nil
}

// entirely based on github.com/boombuler/hid
// https://github.com/boombuler/hid/blob/08a7959390cac69dfd373882ac0a4435765a2545/hid_linux.go#L251
func slice(devices **C.struct_libusb_device, cnt C.ssize_t) []*C.libusb_device {
	var slice []*C.libusb_device
	*(*reflect.SliceHeader)(unsafe.Pointer(&slice)) = reflect.SliceHeader{
		Data: uintptr(unsafe.Pointer(devices)),
		Len:  int(cnt),
		Cap:  int(cnt),
	}
	return slice
}

func (d *usbDevice) write(c command) error {
	if d.handle == nil {
		return errors.New("usb device has not been opend")
	}

	const reportId = 1
	const index = 0
	const timeout = 5000

	data := c.bytes()
	n := len(data)
	written := C.libusb_control_transfer(d.handle,
		C.uint8_t(hidEndpointOut|hidRecipientInterface|hidRequestTypeClass),
		C.uint8_t(hidSetReport),
		C.uint16_t(reportId),
		C.uint16_t(index),
		(*C.uchar)(&data[0]),
		C.uint16_t(n),
		C.uint(timeout),
	)

	if int(written) == n {
		return nil
	}

	return usbError(written)
}

func (d *usbDevice) close() {
	if d == nil || d.handle == nil {
		return
	}

	C.libusb_close(d.handle)
	d.handle = nil
}

type usbError C.int

func (e usbError) Error() string {
	return fmt.Sprintf("libusb: %s [code %d]", usbErrorString[e], int(e))
}

var usbErrorString = map[usbError]string{
	C.LIBUSB_SUCCESS:             "success",
	C.LIBUSB_ERROR_IO:            "i/o error",
	C.LIBUSB_ERROR_INVALID_PARAM: "invalid param",
	C.LIBUSB_ERROR_ACCESS:        "bad access",
	C.LIBUSB_ERROR_NO_DEVICE:     "no device",
	C.LIBUSB_ERROR_NOT_FOUND:     "not found",
	C.LIBUSB_ERROR_BUSY:          "device or resource busy",
	C.LIBUSB_ERROR_TIMEOUT:       "timeout",
	C.LIBUSB_ERROR_OVERFLOW:      "overflow",
	C.LIBUSB_ERROR_PIPE:          "pipe error",
	C.LIBUSB_ERROR_INTERRUPTED:   "interrupted",
	C.LIBUSB_ERROR_NO_MEM:        "out of memory",
	C.LIBUSB_ERROR_NOT_SUPPORTED: "not supported",
	C.LIBUSB_ERROR_OTHER:         "unknown error",
}
<|endoftext|>