<commit_before>package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"path"
)

func init() {
	log.SetFlags(0)
}

func fetch(url string) (filename string, n int64, err error) {
	resp, err := http.Get(url)
	if err != nil {
		return "", 0, err
	}
	defer resp.Body.Close()

	local := path.Base(resp.Request.URL.Path)
	if local == "/" {
		local = "index.html"
	}
	f, err := os.Create(local)
	if err != nil {
		return "", 0, err
	}
	n, err = io.Copy(f, resp.Body)
	// Close file, but prefer error from Copy, if any.
	if closeErr := f.Close(); err == nil {
		err = closeErr
	}
	return local, n, err
}

func main() {
	if len(os.Args) < 2 {
		log.Fatalln("please, specify URL to fetch")
	}
	filename, copied, err := fetch(os.Args[1])
	if err != nil {
		log.Fatalln(err)
	}
	fmt.Printf("%d bytes were copied to %s\n", copied, filename)
}
<commit_msg>[5.18] Solution is added.<commit_after>package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"path"
)

func init() {
	log.SetFlags(0)
}

func fetch(url string) (filename string, n int64, err error) {
	resp, err := http.Get(url)
	if err != nil {
		return "", 0, err
	}
	defer resp.Body.Close()

	local := path.Base(resp.Request.URL.Path)
	if local == "/" {
		local = "index.html"
	}
	f, err := os.Create(local)
	if err != nil {
		return "", 0, err
	}
	// NOTE: not sure this is correct
	defer func() {
		// Close file, but prefer error from Copy, if any.
		if closeErr := f.Close(); err == nil {
			err = closeErr
		}
	}()
	n, err = io.Copy(f, resp.Body)
	return local, n, err
}

func main() {
	if len(os.Args) < 2 {
		log.Fatalln("please, specify URL to fetch")
	}
	filename, copied, err := fetch(os.Args[1])
	if err != nil {
		log.Fatalln(err)
	}
	fmt.Printf("%d bytes were copied to %s\n", copied, filename)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"reflect"

	"github.com/babie/study/cgo/c2go"
)

func main() {
	bt := c2go.GetTrue()
	bf := c2go.GetFalse()
	ni := c2go.GetInt()
	nf := c2go.GetFloat()
	nd := c2go.GetDouble()
	fmt.Printf("GetTrue: %v %#v\n", reflect.TypeOf(bt), bt)
	fmt.Printf("GetFalse: %v %#v\n", reflect.TypeOf(bf), bf)
	fmt.Printf("GetInt: %v %#v\n", reflect.TypeOf(ni), ni)
	fmt.Printf("GetFloat: %v %#v\n", reflect.TypeOf(nf), nf)
	fmt.Printf("GetDouble: %v %#v\n", reflect.TypeOf(nd), nd)
}
<commit_msg>refactor: Remove reflect package from imports.<commit_after>package main

import (
	"fmt"

	"github.com/babie/study/cgo/c2go"
)

func main() {
	fmt.Printf("GetTrue: %#v\n", c2go.GetTrue())
	fmt.Printf("GetFalse: %#v\n", c2go.GetFalse())
	fmt.Printf("GetInt: %#v\n", c2go.GetInt())
	fmt.Printf("GetFloat: %#v\n", c2go.GetFloat())
	fmt.Printf("GetDouble: %#v\n", c2go.GetDouble())
}
<|endoftext|>


<commit_before>package picker

import (
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"strings"
)

var device Device
var port Port
var config Env

func Init(ymlFile string) error {
	data, err := ioutil.ReadFile(ymlFile)
	if err != nil {
		return errors.New("Picker: Open file: " + err.Error())
	}
	config = Env{}
	configErr := config.configure([]byte(data))
	if configErr != nil {
		return configErr
	}
	return nil
}

func MakeFirmWare() error {
	os.Mkdir(".picker", 0777)
	cmd0 := "platformio init --board nanoatmega328 --project-dir .picker" + "\n"
	cmd0 += "platformio lib --global install 525@1.0.0" + "\n" // Adafruit BMP085 Library @ 1.0.0
	cmd0 += "platformio lib --global install 54@3.7.7" + "\n"  // OneWire @ 2.3.2
	cmd0 += "platformio lib --global install 1336@None" // DHTlib@None
	err := runCmd(cmd0)
	if err != nil {
		return err
	}
	hFile, err := config.Device.makeHeader()
	if err != nil {
		return err
	}
	ioutil.WriteFile(".picker/src/config.h", []byte(hFile), 0777)
	source, err := ioutil.ReadFile("../arduino/device.cpp")
	if err != nil {
		return err
	}
	ioutil.WriteFile(".picker/src/device.cpp", source, 0777)
	cmd1 := "platformio run --target upload --project-dir .picker --upload-port " + config.Device.Port
	err = runCmd(cmd1)
	if err != nil {
		return err
	}
	return nil
}

func runCmd(cmdStr string) error {
	cmds := strings.Split(cmdStr, "\n")
	for _, line := range cmds {
		fmt.Println(">>>>>", line)
		c := strings.Split(line, " ")
		createCmd := exec.Command(c[0], c[1:]...)
		var out bytes.Buffer
		createCmd.Stdout = &out
		createCmd.Stderr = &out
		err := createCmd.Run()
		if err != nil {
			return errors.New(err.Error() + ":\n" + out.String())
		}
		fmt.Println(out.String())
	}
	return nil
}

func Create() error {
	port = Port{Name: config.Device.Port, Baud: config.Device.Baud, Timeout: config.Device.TimeOut}
	device = Device{address: config.Device.Address, port: &port, sensors: &sensors{}, dtrReset: config.Device.DTRReset}
	initDeviceError := device.init()
	if initDeviceError != nil {
		return initDeviceError
	}
	pingError := device.ping()
	if pingError != nil {
		return pingError
	}
	return nil
}

func Destroy() error {
	closeDeviceError := device.close()
	return closeDeviceError
}

func ReadSensors() error {
	for _, sensor := range config.Device.Sensors {
		switch sensor.Type {
		case "ds18b20":
			tempErr := device.updateDS1820Sensors()
			if tempErr != nil {
				return tempErr
			}
		case "bmp085":
			pressErr := device.updateBMP085Sensors()
			if pressErr != nil {
				return pressErr
			}
		case "dht22":
			err := device.updateDHT22()
			if err != nil {
				return err
			}
		}
	}
	return nil
}

func GetSensorsRef() *sensors {
	return device.sensors
}
<commit_msg>changed to non depended on OS paths<commit_after>package picker

import (
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"strings"
	"path/filepath"
)

var device Device
var port Port
var config Env

func Init(ymlFile string) error {
	data, err := ioutil.ReadFile(ymlFile)
	if err != nil {
		return errors.New("Picker: Open file: " + err.Error())
	}
	config = Env{}
	configErr := config.configure([]byte(data))
	if configErr != nil {
		return configErr
	}
	return nil
}

func MakeFirmWare() error {
	os.Mkdir(".picker", 0777)
	cmd0 := "platformio init --board nanoatmega328 --project-dir .picker" + "\n"
	cmd0 += "platformio lib --global install 525@1.0.0" + "\n" // Adafruit BMP085 Library @ 1.0.0
	cmd0 += "platformio lib --global install 54@3.7.7" + "\n"  // OneWire @ 2.3.2
	cmd0 += "platformio lib --global install 1336@None" // DHTlib@None
	err := runCmd(cmd0)
	if err != nil {
		return err
	}
	hFile, err := config.Device.makeHeader()
	if err != nil {
		return err
	}
	hPath := filepath.Join(".picker", "src", "config.h")
	ioutil.WriteFile(hPath, []byte(hFile), 0777)
	templatePath := filepath.Join("..", "arduino", "device.cpp")
	source, err := ioutil.ReadFile(templatePath)
	if err != nil {
		return err
	}
	cppPath := filepath.Join(".picker", "src", "device.cpp")
	ioutil.WriteFile(cppPath, source, 0777)
	cmd1 := "platformio run --target upload --project-dir .picker --upload-port " + config.Device.Port
	err = runCmd(cmd1)
	if err != nil {
		return err
	}
	return nil
}

func runCmd(cmdStr string) error {
	cmds := strings.Split(cmdStr, "\n")
	for _, line := range cmds {
		fmt.Println(">>>>", line)
		c := strings.Split(line, " ")
		createCmd := exec.Command(c[0], c[1:]...)
		var out bytes.Buffer
		createCmd.Stdout = &out
		createCmd.Stderr = &out
		err := createCmd.Run()
		if err != nil {
			return errors.New(err.Error() + ":\n" + out.String())
		}
		fmt.Println(out.String())
	}
	return nil
}

func Create() error {
	port = Port{Name: config.Device.Port, Baud: config.Device.Baud, Timeout: config.Device.TimeOut}
	device = Device{address: config.Device.Address, port: &port, sensors: &sensors{}, dtrReset: config.Device.DTRReset}
	initDeviceError := device.init()
	if initDeviceError != nil {
		return initDeviceError
	}
	pingError := device.ping()
	if pingError != nil {
		return pingError
	}
	return nil
}

func Destroy() error {
	closeDeviceError := device.close()
	return closeDeviceError
}

func ReadSensors() error {
	for _, sensor := range config.Device.Sensors {
		switch sensor.Type {
		case "ds18b20":
			tempErr := device.updateDS1820Sensors()
			if tempErr != nil {
				return tempErr
			}
		case "bmp085":
			pressErr := device.updateBMP085Sensors()
			if pressErr != nil {
				return pressErr
			}
		case "dht22":
			err := device.updateDHT22()
			if err != nil {
				return err
			}
		}
	}
	return nil
}

func GetSensorsRef() *sensors {
	return device.sensors
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"github.com/drone/drone-template-lib/template"
)

const (
	// DroneIconURL default drone logo url
	DroneIconURL = "https://c1.staticflickr.com/5/4236/34957940160_435d83114f_z.jpg"
	// DroneDesc default drone description
	DroneDesc = "Powered by Drone Discord Plugin"
)

type (
	// GitHub information.
	GitHub struct {
		Workflow  string
		Workspace string
		Action    string
		EventName string
		EventPath string
	}

	// Repo information.
	Repo struct {
		FullName  string
		Namespace string
		Name      string
	}

	// Commit information.
	Commit struct {
		Sha     string
		Ref     string
		Branch  string
		Link    string
		Author  string
		Avatar  string
		Email   string
		Message string
	}

	// Build information.
	Build struct {
		Tag      string
		Event    string
		Number   int
		Status   string
		Link     string
		Started  float64
		Finished float64
		PR       string
		DeployTo string
	}

	// Config for the plugin.
	Config struct {
		WebhookID    string
		WebhookToken string
		Color        string
		Message      []string
		File         []string
		Drone        bool
		GitHub       bool
	}

	// EmbedFooterObject for Embed Footer Structure.
	EmbedFooterObject struct {
		Text    string `json:"text"`
		IconURL string `json:"icon_url"`
	}

	// EmbedAuthorObject for Embed Author Structure
	EmbedAuthorObject struct {
		Name    string `json:"name"`
		URL     string `json:"url"`
		IconURL string `json:"icon_url"`
	}

	// EmbedFieldObject for Embed Field Structure
	EmbedFieldObject struct {
		Name  string `json:"name"`
		Value string `json:"value"`
	}

	// EmbedObject is for Embed Structure
	EmbedObject struct {
		Title       string             `json:"title"`
		Description string             `json:"description"`
		URL         string             `json:"url"`
		Color       int                `json:"color"`
		Footer      EmbedFooterObject  `json:"footer"`
		Author      EmbedAuthorObject  `json:"author"`
		Fields      []EmbedFieldObject `json:"fields"`
	}

	// Payload struct
	Payload struct {
		Wait      bool          `json:"wait"`
		Content   string        `json:"content"`
		Username  string        `json:"username"`
		AvatarURL string        `json:"avatar_url"`
		TTS       bool          `json:"tts"`
		Embeds    []EmbedObject `json:"embeds"`
	}

	// Plugin values.
	Plugin struct {
		GitHub  GitHub
		Repo    Repo
		Build   Build
		Config  Config
		Payload Payload
		Commit  Commit
	}
)

func templateMessage(t string, plugin Plugin) (string, error) {
	return template.RenderTrim(t, plugin)
}

// Creates a new file upload http request with optional extra params
// https://matt.aimonetti.net/posts/2013/07/01/golang-multipart-file-upload-example/
func newfileUploadRequest(uri string, params map[string]string, paramName, path string) (*http.Request, error) {
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)
	part, err := writer.CreateFormFile(paramName, filepath.Base(path))
	if err != nil {
		return nil, err
	}
	_, err = io.Copy(part, file)

	for key, val := range params {
		_ = writer.WriteField(key, val)
	}
	err = writer.Close()
	if err != nil {
		return nil, err
	}

	req, err := http.NewRequest("POST", uri, body)
	req.Header.Set("Content-Type", writer.FormDataContentType())
	return req, err
}

// Exec executes the plugin.
func (p *Plugin) Exec() error {
	if p.Config.WebhookID == "" || p.Config.WebhookToken == "" {
		return errors.New("missing discord config")
	}

	if len(p.Config.Message) == 0 {
		object := p.Template()
		p.Payload.Embeds = []EmbedObject{object}
		err := p.SendMessage()
		if err != nil {
			return err
		}
	}

	if len(p.Config.Message) > 0 {
		for _, m := range p.Config.Message {
			txt, err := templateMessage(m, *p)
			if err != nil {
				return err
			}

			if len(p.Config.Color) != 0 {
				object := p.DefaultTemplate(txt)
				p.Payload.Embeds = append(p.Payload.Embeds, object)
			} else {
				p.Payload.Content = txt
				err = p.SendMessage()
				if err != nil {
					return err
				}
			}
		}

		if len(p.Payload.Embeds) > 0 {
			err := p.SendMessage()
			if err != nil {
				return err
			}
		}
	}

	fmt.Println(p.Config.File)
	fmt.Println(len(p.Config.File))
	for _, f := range p.Config.File {
		if f == "" {
			continue
		}
		err := p.SendFile(f)
		if err != nil {
			return err
		}
	}

	return nil
}

// SendFile upload file to discord
func (p *Plugin) SendFile(file string) error {
	webhookURL := fmt.Sprintf("https://discordapp.com/api/webhooks/%s/%s", p.Config.WebhookID, p.Config.WebhookToken)
	extraParams := map[string]string{}

	if p.Payload.Username != "" {
		extraParams["username"] = p.Payload.Username
	}

	if p.Payload.AvatarURL != "" {
		extraParams["avatar_url"] = p.Payload.AvatarURL
	}

	if p.Payload.TTS {
		extraParams["tts"] = "true"
	}

	request, err := newfileUploadRequest(
		webhookURL,
		extraParams,
		"file",
		file,
	)
	if err != nil {
		return err
	}
	client := &http.Client{}
	_, err = client.Do(request)
	if err != nil {
		return err
	}

	return nil
}

// SendMessage to send discord message.
func (p *Plugin) SendMessage() error {
	webhookURL := fmt.Sprintf("https://discordapp.com/api/webhooks/%s/%s", p.Config.WebhookID, p.Config.WebhookToken)
	b := new(bytes.Buffer)
	if err := json.NewEncoder(b).Encode(p.Payload); err != nil {
		return err
	}
	_, err := http.Post(webhookURL, "application/json; charset=utf-8", b)

	if err != nil {
		return err
	}

	return nil
}

// DefaultTemplate is plugin default template for Drone CI.
func (p *Plugin) DefaultTemplate(title string) EmbedObject {
	return EmbedObject{
		Title: title,
		Color: p.Color(),
	}
}

// Template is plugin default template for Drone CI or GitHub Action.
func (p *Plugin) Template() EmbedObject {
	if p.Config.GitHub {
		message := fmt.Sprintf("%s/%s triggered by %s (%s)",
			p.Repo.FullName,
			p.GitHub.Workflow,
			p.Repo.Namespace,
			p.GitHub.EventName,
		)

		return EmbedObject{
			Title: message,
			Color: p.Color(),
			Footer: EmbedFooterObject{
				Text:    DroneDesc,
				IconURL: DroneIconURL,
			},
		}
	}

	description := ""
	switch p.Build.Event {
	case "push":
		description = fmt.Sprintf("%s pushed to %s", p.Commit.Author, p.Commit.Branch)
	case "pull_request":
		branch := ""
		if p.Commit.Ref != "" {
			branch = p.Commit.Ref
		} else {
			branch = p.Commit.Branch
		}
		description = fmt.Sprintf("%s updated pull request %s", p.Commit.Author, branch)
	case "tag":
		description = fmt.Sprintf("%s pushed tag %s", p.Commit.Author, p.Commit.Branch)
	}

	return EmbedObject{
		Title:       p.Commit.Message,
		Description: description,
		URL:         p.Build.Link,
		Color:       p.Color(),
		Author: EmbedAuthorObject{
			Name:    p.Commit.Author,
			IconURL: p.Commit.Avatar,
		},
		Footer: EmbedFooterObject{
			Text:    DroneDesc,
			IconURL: DroneIconURL,
		},
	}
}

// Clear reset to default
func (p *Plugin) Clear() {
	// clear content field.
	p.Payload.Content = ""
	p.Payload.Embeds = []EmbedObject{}
}

// Color code of the embed
func (p *Plugin) Color() int {
	if p.Config.Color != "" {
		p.Config.Color = strings.Replace(p.Config.Color, "#", "", -1)
		if s, err := strconv.ParseInt(p.Config.Color, 16, 32); err == nil {
			return int(s)
		}
	}

	switch p.Build.Status {
	case "success":
		// green
		return 0x1ac600
	case "failure", "error", "killed":
		// red
		return 0xff3232
	default:
		// yellow
		return 0xffd930
	}
}
<commit_msg>chore: remove debug message<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"github.com/drone/drone-template-lib/template"
)

const (
	// DroneIconURL default drone logo url
	DroneIconURL = "https://c1.staticflickr.com/5/4236/34957940160_435d83114f_z.jpg"
	// DroneDesc default drone description
	DroneDesc = "Powered by Drone Discord Plugin"
)

type (
	// GitHub information.
	GitHub struct {
		Workflow  string
		Workspace string
		Action    string
		EventName string
		EventPath string
	}

	// Repo information.
	Repo struct {
		FullName  string
		Namespace string
		Name      string
	}

	// Commit information.
	Commit struct {
		Sha     string
		Ref     string
		Branch  string
		Link    string
		Author  string
		Avatar  string
		Email   string
		Message string
	}

	// Build information.
	Build struct {
		Tag      string
		Event    string
		Number   int
		Status   string
		Link     string
		Started  float64
		Finished float64
		PR       string
		DeployTo string
	}

	// Config for the plugin.
	Config struct {
		WebhookID    string
		WebhookToken string
		Color        string
		Message      []string
		File         []string
		Drone        bool
		GitHub       bool
	}

	// EmbedFooterObject for Embed Footer Structure.
	EmbedFooterObject struct {
		Text    string `json:"text"`
		IconURL string `json:"icon_url"`
	}

	// EmbedAuthorObject for Embed Author Structure
	EmbedAuthorObject struct {
		Name    string `json:"name"`
		URL     string `json:"url"`
		IconURL string `json:"icon_url"`
	}

	// EmbedFieldObject for Embed Field Structure
	EmbedFieldObject struct {
		Name  string `json:"name"`
		Value string `json:"value"`
	}

	// EmbedObject is for Embed Structure
	EmbedObject struct {
		Title       string             `json:"title"`
		Description string             `json:"description"`
		URL         string             `json:"url"`
		Color       int                `json:"color"`
		Footer      EmbedFooterObject  `json:"footer"`
		Author      EmbedAuthorObject  `json:"author"`
		Fields      []EmbedFieldObject `json:"fields"`
	}

	// Payload struct
	Payload struct {
		Wait      bool          `json:"wait"`
		Content   string        `json:"content"`
		Username  string        `json:"username"`
		AvatarURL string        `json:"avatar_url"`
		TTS       bool          `json:"tts"`
		Embeds    []EmbedObject `json:"embeds"`
	}

	// Plugin values.
	Plugin struct {
		GitHub  GitHub
		Repo    Repo
		Build   Build
		Config  Config
		Payload Payload
		Commit  Commit
	}
)

func templateMessage(t string, plugin Plugin) (string, error) {
	return template.RenderTrim(t, plugin)
}

// Creates a new file upload http request with optional extra params
// https://matt.aimonetti.net/posts/2013/07/01/golang-multipart-file-upload-example/
func newfileUploadRequest(uri string, params map[string]string, paramName, path string) (*http.Request, error) {
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)
	part, err := writer.CreateFormFile(paramName, filepath.Base(path))
	if err != nil {
		return nil, err
	}
	_, err = io.Copy(part, file)

	for key, val := range params {
		_ = writer.WriteField(key, val)
	}
	err = writer.Close()
	if err != nil {
		return nil, err
	}

	req, err := http.NewRequest("POST", uri, body)
	req.Header.Set("Content-Type", writer.FormDataContentType())
	return req, err
}

// Exec executes the plugin.
func (p *Plugin) Exec() error {
	if p.Config.WebhookID == "" || p.Config.WebhookToken == "" {
		return errors.New("missing discord config")
	}

	if len(p.Config.Message) == 0 {
		object := p.Template()
		p.Payload.Embeds = []EmbedObject{object}
		err := p.SendMessage()
		if err != nil {
			return err
		}
	}

	if len(p.Config.Message) > 0 {
		for _, m := range p.Config.Message {
			txt, err := templateMessage(m, *p)
			if err != nil {
				return err
			}

			if len(p.Config.Color) != 0 {
				object := p.DefaultTemplate(txt)
				p.Payload.Embeds = append(p.Payload.Embeds, object)
			} else {
				p.Payload.Content = txt
				err = p.SendMessage()
				if err != nil {
					return err
				}
			}
		}

		if len(p.Payload.Embeds) > 0 {
			err := p.SendMessage()
			if err != nil {
				return err
			}
		}
	}

	for _, f := range p.Config.File {
		if f == "" {
			continue
		}
		err := p.SendFile(f)
		if err != nil {
			return err
		}
	}

	return nil
}

// SendFile upload file to discord
func (p *Plugin) SendFile(file string) error {
	webhookURL := fmt.Sprintf("https://discordapp.com/api/webhooks/%s/%s", p.Config.WebhookID, p.Config.WebhookToken)
	extraParams := map[string]string{}

	if p.Payload.Username != "" {
		extraParams["username"] = p.Payload.Username
	}

	if p.Payload.AvatarURL != "" {
		extraParams["avatar_url"] = p.Payload.AvatarURL
	}

	if p.Payload.TTS {
		extraParams["tts"] = "true"
	}

	request, err := newfileUploadRequest(
		webhookURL,
		extraParams,
		"file",
		file,
	)
	if err != nil {
		return err
	}
	client := &http.Client{}
	_, err = client.Do(request)
	if err != nil {
		return err
	}

	return nil
}

// SendMessage to send discord message.
func (p *Plugin) SendMessage() error {
	webhookURL := fmt.Sprintf("https://discordapp.com/api/webhooks/%s/%s", p.Config.WebhookID, p.Config.WebhookToken)
	b := new(bytes.Buffer)
	if err := json.NewEncoder(b).Encode(p.Payload); err != nil {
		return err
	}
	_, err := http.Post(webhookURL, "application/json; charset=utf-8", b)

	if err != nil {
		return err
	}

	return nil
}

// DefaultTemplate is plugin default template for Drone CI.
func (p *Plugin) DefaultTemplate(title string) EmbedObject {
	return EmbedObject{
		Title: title,
		Color: p.Color(),
	}
}

// Template is plugin default template for Drone CI or GitHub Action.
func (p *Plugin) Template() EmbedObject {
	if p.Config.GitHub {
		message := fmt.Sprintf("%s/%s triggered by %s (%s)",
			p.Repo.FullName,
			p.GitHub.Workflow,
			p.Repo.Namespace,
			p.GitHub.EventName,
		)

		return EmbedObject{
			Title: message,
			Color: p.Color(),
			Footer: EmbedFooterObject{
				Text:    DroneDesc,
				IconURL: DroneIconURL,
			},
		}
	}

	description := ""
	switch p.Build.Event {
	case "push":
		description = fmt.Sprintf("%s pushed to %s", p.Commit.Author, p.Commit.Branch)
	case "pull_request":
		branch := ""
		if p.Commit.Ref != "" {
			branch = p.Commit.Ref
		} else {
			branch = p.Commit.Branch
		}
		description = fmt.Sprintf("%s updated pull request %s", p.Commit.Author, branch)
	case "tag":
		description = fmt.Sprintf("%s pushed tag %s", p.Commit.Author, p.Commit.Branch)
	}

	return EmbedObject{
		Title:       p.Commit.Message,
		Description: description,
		URL:         p.Build.Link,
		Color:       p.Color(),
		Author: EmbedAuthorObject{
			Name:    p.Commit.Author,
			IconURL: p.Commit.Avatar,
		},
		Footer: EmbedFooterObject{
			Text:    DroneDesc,
			IconURL: DroneIconURL,
		},
	}
}

// Clear reset to default
func (p *Plugin) Clear() {
	// clear content field.
	p.Payload.Content = ""
	p.Payload.Embeds = []EmbedObject{}
}

// Color code of the embed
func (p *Plugin) Color() int {
	if p.Config.Color != "" {
		p.Config.Color = strings.Replace(p.Config.Color, "#", "", -1)
		if s, err := strconv.ParseInt(p.Config.Color, 16, 32); err == nil {
			return int(s)
		}
	}

	switch p.Build.Status {
	case "success":
		// green
		return 0x1ac600
	case "failure", "error", "killed":
		// red
		return 0xff3232
	default:
		// yellow
		return 0xffd930
	}
}
<|endoftext|>


<commit_before>//  Author: Kevin Barry
//  Date:   27/09/2017
//  Description : function to calculate the square root of a number using Newton’s method.
package main

	import {
import "fmt"
import "fmt"
		"fmt"//import for input/output
		"math"// import for math (math.Sqrt(x))
	}//imports

	//function to run newthons method
	func z_next(z float64,x float64)float64{
		return z - (((z*x) - x) / (2*z))
	}//z_next

	func main(){
		//number to calculate square root
		x := 20.0

		//initial guess
		z :=  float64(1)

		//loop through using newtons method until next guess == current guess
		for z = 1.0; z != z_next(z,x); z = z_next(z,x){
			//display current guess
			fmt.Println("The current Guess is %12.8f \n ",z)
		}//for

		fmt.Println("The square of %f")
	}//main<commit_msg>problem 9 complete<commit_after>//  Author: Kevin Barry
//  Date:   27/09/2017
//  Description : function to calculate the square root of a number using Newton’s method.
// Adapted from 9. on https://data-representation.github.io/problems/go-fundamentals.html

package main

import "fmt"//import for input/output
import "math"// import for math (math.Sqrt(x))

	//function to run newthons method
	func newton(x float64,z float64)float64{
		//var y float64  =	z - (((z*x) - x) / (2*z))
		return z - (((z*z) - x) / (2*z))

	}//newton

	func main(){

		var counter int =0;
		var x float64;
		//number to calculate square root
		//take user input from console
		fmt.Printf("Newtons Theory Square Root Calculator")
		fmt.Printf("\n=====================================")
		fmt.Print("\nPlease enter a number to test:")
		fmt.Scan(&x)
		fmt.Print("\n")

		//initial guess
		z :=  float64(1)

		//loop through using newtons method until next guess == current guess
		for z = 1.0; z != newton(x,z); z = newton(x,z){
		//for z = 1.0; z_next(x,z)<math.Sqrt(x); z = z_next(x,z){
			//display current guess
			counter++
			fmt.Printf("Guess %d :%12.10f \n",counter,z)
		}//for

		fmt.Printf("The square of %.2f is %12.10f according to Newtons Theory\n",x,z)
		fmt.Printf("The square of %.2f is %.8f according to 'math.Sqrt(x)'",x,math.Sqrt(x))

	}//main<|endoftext|>


<commit_before>package num

import (
	"bytes"
	"sort"
	"strconv"
)

func largestNum(nums []int) string {
	return useBucket(nums)
}

// useBucket time complexity O(N+k*logk), space complexity O(N)
func useBucket(nums []int) string {
	bkt := [10][]int{}
	for _, num := range nums {
		tmp := num
		for tmp >= 10 {
			tmp /= 10
		}
		bkt[tmp] = append(bkt[tmp], num)
	}
	var buf bytes.Buffer
	for i := 9; i >= 0; i-- {
		// sort bkt[i] based on the combinantion of string values
		vec := bkt[i]
		if len(vec) > 1 {
			sort.Slice(vec, func(i, j int) bool {
				si, sj := strconv.Itoa(vec[i]), strconv.Itoa(vec[j])
				return si+sj > sj+si
			})
		}
		for _, num := range vec {
			buf.WriteString(strconv.Itoa(num))
		}
	}
	ans := buf.String()
	if ans[0] == '0' {
		return "0"
	}
	return ans
}
<commit_msg>solve 179 use just sorting.<commit_after>package num

import (
	"bytes"
	"sort"
	"strconv"
)

func largestNum(nums []int) string {
	return useBucket(nums)
}

// useBucket time complexity O(N+k*logk), space complexity O(N)
func useBucket(nums []int) string {
	bkt := [10][]int{}
	for _, num := range nums {
		tmp := num
		for tmp >= 10 {
			tmp /= 10
		}
		bkt[tmp] = append(bkt[tmp], num)
	}
	var buf bytes.Buffer
	for i := 9; i >= 0; i-- {
		// sort bkt[i] based on the combinantion of string values
		vec := bkt[i]
		if len(vec) > 1 {
			sort.Slice(vec, func(i, j int) bool {
				si, sj := strconv.Itoa(vec[i]), strconv.Itoa(vec[j])
				return si+sj > sj+si
			})
		}
		for _, num := range vec {
			buf.WriteString(strconv.Itoa(num))
		}
	}
	ans := buf.String()
	if ans[0] == '0' {
		return "0"
	}
	return ans
}

// useSorting time complexity O(N*K*logK) space complexity O(N) where K is the average length of each number.
func useSorting(nums []int) string {
	// just sort the nums based on the combination of two
	sort.Slice(nums, func(i, j int) bool {
		si, sj := strconv.Itoa(nums[i]), strconv.Itoa(nums[j])
		return si+sj > sj+si
	})
	var sb bytes.Buffer
	for _, num := range nums {
		sb.WriteString(strconv.Itoa(num))
	}
	ans := sb.String()
	if ans[0] == '0' {
		return "0"
	}
	return ans
}
<|endoftext|>


<commit_before>// pounce.go
package main

import (
	"bufio"
	"flag"
	"fmt"
	"github.com/guelfey/go.dbus"
	"io"
	"net/http"
	"os"
	"strings"
	"time"
)

// download takes a url of type string as an argument
// and returns a response pointer.
func download(url string) *http.Response {

	fmt.Printf("Downloading...\n")
	resp, err := http.Get(url)

	if err != nil {
		panic(err)
	}
	fmt.Printf("Download complete!\n")

	return resp
}

// create takes a filename of type string as an argument
// and returns a file pointer.  It basically calls
// os.Create(filename) and checks err.
func create(filename string) *os.File {

	file, err := os.Create(filename)

	if err != nil {
		panic(err)
	}

	fmt.Printf("Created %v ...\n", filename)

	return file
}

func multiDownload(url, destination string, channel chan<- bool) {

	fmt.Printf("Downloading...\n")
	resp, err := http.Get(url)
	createDone := make(chan bool)
	go multiCreate(destination, resp, createDone)

	if err != nil {
		panic(err)
	}
	fmt.Printf("Download complete!\n")
	<-createDone
	channel <- true
}

func multiCreate(destination string, response *http.Response, createDone chan<- bool) {

	fmt.Printf("Creating %v ...\n", destination)
	file, err := os.Create(destination)
	defer file.Close()

	if err != nil {
		panic(err)
	}

	fmt.Printf("Writing file %v...\n", destination)
	complete, err := io.Copy(file, response.Body)
	defer response.Body.Close()
	fmt.Println(complete)

	if err != nil {
		panic(err)
	}

	createDone <- true
}

func readFile(infilename, destination string) {

	file, err := os.Open(infilename)

	if err != nil {
		panic(err)
	}

	scanner := bufio.NewScanner(file)

	lineCount := 0
	channel := make(chan bool)
	for scanner.Scan() {
		lineCount++

		line := scanner.Text()
		splitCount := strings.Count(line, "/")
		endOfSplit := strings.SplitAfterN(line, "/", splitCount)
		filename := string(endOfSplit[len(endOfSplit)-1])

		if strings.Count(filename, "/") > 0 {
			filename = string(strings.SplitAfterN(filename, "/", 2)[1])
		}

		toSave := fmt.Sprintf("%v%v", destination, filename)
		go multiDownload(line, toSave, channel)
	}

	if err := scanner.Err(); err != nil {
		panic(err)
	}

	for i := 0; i < lineCount; i++ {
		<-channel
	}
}

// save takes a file of type io.Writer and a response pointer
// as an argument so that it can return a size as type int64.
// It calls io.Copy, handles any errors, and returns.
func save(file io.Writer, resp *http.Response) int64 {

	fmt.Printf("Writing file...\n")
	complete, err := io.Copy(file, resp.Body)

	if err != nil {
		panic(err)
	}

	return complete
}

// notify takes a message string and channel as an
// argument and displays a dbus notification.
func notify(msg string, done chan<- bool) {

	conn, err := dbus.SessionBus()

	if err != nil {
		panic(err)
	}

	obj := conn.Object("org.freedesktop.Notifications", "/org/freedesktop/Notifications")
	call := obj.Call("org.freedesktop.Notifications.Notify", 0, "", uint32(0),
		"", "GoPounce", msg, []string{}, map[string]dbus.Variant{}, int32(5000))

	if call.Err != nil {
		panic(call.Err)
	}
	done <- true
}

func main() {

	var input string
	var output string
	done := make(chan bool)

	flag.StringVar(&input, "url", "", "URL to get")
	flag.StringVar(&input, "infile", "", "An input file with URLs on each line that are newline delimitted.")
	flag.StringVar(&output, "filename", "", "Destination file to write.")
	flag.StringVar(&output, "directory", "", "Destination directory to write into with trailing '/' (only works with -infile flag)")
	flag.Parse()
	flag.Args()

	if input == "" {
		input = flag.Arg(0)
	}

	if output == "" {
		output = flag.Arg(1)
	}

	start := time.Now()

	// TODO: Refactor, this doesn't conform to DRY.
	if strings.Contains(input, "http") || strings.Contains(input, "www") {
		resp := download(input)
		defer resp.Body.Close()
		file := create(output)
		defer file.Close()
		complete := save(file, resp)

		end := time.Now()
		size := complete / 1024
		msg := fmt.Sprintf("Downloaded ~%v kb in %v \n", size, end.Sub(start))

		go notify(msg, done)
		fmt.Printf(msg)
		<-done
	} else {
		readFile(input, output)
		end := time.Now()
		msg := fmt.Sprintf("Downloaded contents of %v in %v\n", input, end.Sub(start))
		go notify(msg, done)
		fmt.Printf(msg)
		<-done
	}
}
<commit_msg>send 'true' back to readFile on channel channel before receiving from channel createDone, that keeps multiCreate from blocking the completion of multiDownload and allows out of order downloading and file writing.<commit_after>// pounce.go
package main

import (
	"bufio"
	"flag"
	"fmt"
	"github.com/guelfey/go.dbus"
	"io"
	"net/http"
	"os"
	"strings"
	"time"
)

// download takes a url of type string as an argument
// and returns a response pointer.
func download(url string) *http.Response {

	fmt.Printf("Downloading...\n")
	resp, err := http.Get(url)

	if err != nil {
		panic(err)
	}
	fmt.Printf("Download complete!\n")

	return resp
}

// create takes a filename of type string as an argument
// and returns a file pointer.  It basically calls
// os.Create(filename) and checks err.
func create(filename string) *os.File {

	file, err := os.Create(filename)

	if err != nil {
		panic(err)
	}

	fmt.Printf("Created %v ...\n", filename)

	return file
}

func multiDownload(url, destination string, channel chan<- bool) {

	fmt.Printf("Downloading...\n")
	resp, err := http.Get(url)
	createDone := make(chan bool)
	go multiCreate(destination, resp, createDone)

	if err != nil {
		panic(err)
	}
	fmt.Printf("Download complete!\n")
	channel <- true
	<-createDone
}

func multiCreate(destination string, response *http.Response, createDone chan<- bool) {

	fmt.Printf("Creating %v ...\n", destination)
	file, err := os.Create(destination)
	defer file.Close()

	if err != nil {
		panic(err)
	}

	fmt.Printf("Writing file %v...\n", destination)
	complete, err := io.Copy(file, response.Body)
	defer response.Body.Close()
	fmt.Println(complete)

	if err != nil {
		panic(err)
	}

	createDone <- true
}

func readFile(infilename, destination string) {

	file, err := os.Open(infilename)

	if err != nil {
		panic(err)
	}

	scanner := bufio.NewScanner(file)

	lineCount := 0
	channel := make(chan bool)
	for scanner.Scan() {
		lineCount++

		line := scanner.Text()
		splitCount := strings.Count(line, "/")
		endOfSplit := strings.SplitAfterN(line, "/", splitCount)
		filename := string(endOfSplit[len(endOfSplit)-1])

		if strings.Count(filename, "/") > 0 {
			filename = string(strings.SplitAfterN(filename, "/", 2)[1])
		}

		toSave := fmt.Sprintf("%v%v", destination, filename)
		go multiDownload(line, toSave, channel)
	}

	if err := scanner.Err(); err != nil {
		panic(err)
	}

	for i := 0; i < lineCount; i++ {
		<-channel
	}
}

// save takes a file of type io.Writer and a response pointer
// as an argument so that it can return a size as type int64.
// It calls io.Copy, handles any errors, and returns.
func save(file io.Writer, resp *http.Response) int64 {

	fmt.Printf("Writing file...\n")
	complete, err := io.Copy(file, resp.Body)

	if err != nil {
		panic(err)
	}

	return complete
}

// notify takes a message string and channel as an
// argument and displays a dbus notification.
func notify(msg string, done chan<- bool) {

	conn, err := dbus.SessionBus()

	if err != nil {
		panic(err)
	}

	obj := conn.Object("org.freedesktop.Notifications", "/org/freedesktop/Notifications")
	call := obj.Call("org.freedesktop.Notifications.Notify", 0, "", uint32(0),
		"", "GoPounce", msg, []string{}, map[string]dbus.Variant{}, int32(5000))

	if call.Err != nil {
		panic(call.Err)
	}
	done <- true
}

func main() {

	var input string
	var output string
	done := make(chan bool)

	flag.StringVar(&input, "url", "", "URL to get")
	flag.StringVar(&input, "infile", "", "An input file with URLs on each line that are newline delimitted.")
	flag.StringVar(&output, "filename", "", "Destination file to write.")
	flag.StringVar(&output, "directory", "", "Destination directory to write into with trailing '/' (only works with -infile flag)")
	flag.Parse()
	flag.Args()

	if input == "" {
		input = flag.Arg(0)
	}

	if output == "" {
		output = flag.Arg(1)
	}

	start := time.Now()

	// TODO: Refactor, this doesn't conform to DRY.
	if strings.Contains(input, "http") || strings.Contains(input, "www") {
		resp := download(input)
		defer resp.Body.Close()
		file := create(output)
		defer file.Close()
		complete := save(file, resp)

		end := time.Now()
		size := complete / 1024
		msg := fmt.Sprintf("Downloaded ~%v kb in %v \n", size, end.Sub(start))

		go notify(msg, done)
		fmt.Printf(msg)
		<-done
	} else {
		readFile(input, output)
		end := time.Now()
		msg := fmt.Sprintf("Downloaded contents of %v in %v\n", input, end.Sub(start))
		go notify(msg, done)
		fmt.Printf(msg)
		<-done
	}
}
<|endoftext|>


<commit_before>
// This package provides a priority queue implementation and
// scaffold interfaces.
//
// Addition to original package, this package adds method and
// other internals for inserting only unique items in queue
//
// Copyright (C) 2015 by Milos Mileusnic <milos@groowe.com>
//
// Copyright (C) 2011 by Krzysztof Kowalik <chris@nu7hat.ch>
package pqueue

import (
	"container/heap"
	"errors"
	"sync"
)

// Only items implementing this interface can be enqueued
// on the priority queue.
type QueueItem interface {
	Less(other interface{}) bool
	Id() interface{}
}

// Queue is a threadsafe priority queue exchange. Here's
// a trivial example of usage:
//
//     q := pqueue.New(0)
//     go func() {
//         for {
//             task := q.Dequeue()
//             println(task.(*CustomTask).Name)
//         }
//     }()
//     for i := 0; i < 100; i := 1 {
//         task := CustomTask{Name: "foo", priority: rand.Intn(10)}
//         q.Enqueue(&task)
//     }
//
type Queue struct {
	Limit int
	history map[interface{}]struct{}
	items *sorter
	cond  *sync.Cond
}

// New creates and initializes a new priority queue, taking
// a limit as a parameter. If 0 given, then queue will be
// unlimited.
func New(max int) (q *Queue) {
	var locker sync.Mutex
	q = &Queue{Limit: max}
	q.history = make(map[interface{}]struct{}, 0);
	q.items = new(sorter)
	q.cond = sync.NewCond(&locker)
	heap.Init(q.items)
	return
}

// Enqueue puts given item to the queue.
// Lock the queue and calls enqueue()
func (q *Queue) Enqueue(item QueueItem) (err error) {
	q.cond.L.Lock()
	defer q.cond.L.Unlock()
	return q.enqueue(item)
}

// Enqueue puts given item to the queue.
func (q *Queue) enqueue(item QueueItem) (err error) {
	if q.Limit > 0 && q.Len() >= q.Limit {
		return errors.New("Queue limit reached")
	}
	q.history[item.Id()] = struct{}{};
	heap.Push(q.items, item)
	q.cond.Signal()
	return
}

// check if item already exists in queue (or it has been into queue)
func (q *Queue) Exists(item QueueItem) bool {
	q.cond.L.Lock()
	defer q.cond.L.Unlock()
	return q.exists(item)
}

func (q *Queue) exists(item QueueItem) bool {
	if _, ok := q.history[item.Id()]; ok {
		return true;
	} else {
		return false;
	}
}

// Enqueue puts item in queue only if it hasn't already been in queue
func (q *Queue) EnqueueUnique(item QueueItem) (err error) {
	q.cond.L.Lock()
	defer q.cond.L.Unlock()
	if !q.exists(item) {
		q.enqueue(item)
	}
	return
}

// Dequeue takes an item from the queue. If queue is empty
// then should block waiting for at least one item.
func (q *Queue) Dequeue() (item QueueItem) {
	q.cond.L.Lock()
	defer q.cond.L.Unlock()
	var x interface{}
	for {
		x = heap.Pop(q.items)
		if x == nil {
			q.cond.Wait()
		} else {
			break
		}
	}
	item = x.(QueueItem)
	return
}

// Safely changes enqueued items limit. When limit is set
// to 0, then queue is unlimited.
func (q *Queue) ChangeLimit(newLimit int) {
	q.cond.L.Lock()
	defer q.cond.L.Unlock()
	q.Limit = newLimit
}

// Len returns number of enqueued elemnents.
func (q *Queue) Len() int {
	return q.items.Len()
}

// IsEmpty returns true if queue is empty.
func (q *Queue) IsEmpty() bool {
	return q.Len() == 0
}

type sorter []QueueItem

func (s *sorter) Push(i interface{}) {
	item, ok := i.(QueueItem)
	if !ok {
		return
	}
	*s = append((*s)[:], item)
}

func (s *sorter) Pop() (x interface{}) {
	if s.Len() > 0 {
		l := s.Len()-1
		x = (*s)[l]
		(*s)[l] = nil
		*s = (*s)[:l]
	}
	return
}

func (s *sorter) Len() int {
	return len((*s)[:])
}

func (s *sorter) Less(i, j int) bool {
	return (*s)[i].Less((*s)[j])
}

func (s *sorter) Swap(i, j int) {
	if s.Len() > 0 {
		(*s)[i], (*s)[j] = (*s)[j], (*s)[i]
	}
}<commit_msg>Added function for celaring history<commit_after>// This package provides a priority queue implementation and
// scaffold interfaces.
//
// Addition to original package, this package adds method and
// other internals for inserting only unique items in queue
//
// Copyright (C) 2015 by Milos Mileusnic <milos@groowe.com>
//
// Copyright (C) 2011 by Krzysztof Kowalik <chris@nu7hat.ch>
package pqueue

import (
	"container/heap"
	"errors"
	"sync"
)

// Only items implementing this interface can be enqueued
// on the priority queue.
type QueueItem interface {
	Less(other interface{}) bool
	Id() interface{}
}

// Queue is a threadsafe priority queue exchange. Here's
// a trivial example of usage:
//
//     q := pqueue.New(0)
//     go func() {
//         for {
//             task := q.Dequeue()
//             println(task.(*CustomTask).Name)
//         }
//     }()
//     for i := 0; i < 100; i := 1 {
//         task := CustomTask{Name: "foo", priority: rand.Intn(10)}
//         q.Enqueue(&task)
//     }
//
type Queue struct {
	Limit   int
	history map[interface{}]struct{}
	items   *sorter
	cond    *sync.Cond
}

// New creates and initializes a new priority queue, taking
// a limit as a parameter. If 0 given, then queue will be
// unlimited.
func New(max int) (q *Queue) {
	var locker sync.Mutex
	q = &Queue{Limit: max}
	q.history = make(map[interface{}]struct{}, 0)
	q.items = new(sorter)
	q.cond = sync.NewCond(&locker)
	heap.Init(q.items)
	return
}

// Enqueue puts given item to the queue.
// Lock the queue and calls enqueue()
func (q *Queue) Enqueue(item QueueItem) (err error) {
	q.cond.L.Lock()
	defer q.cond.L.Unlock()
	return q.enqueue(item)
}

// Enqueue puts given item to the queue.
func (q *Queue) enqueue(item QueueItem) (err error) {
	if q.Limit > 0 && q.Len() >= q.Limit {
		return errors.New("Queue limit reached")
	}
	q.history[item.Id()] = struct{}{}
	heap.Push(q.items, item)
	q.cond.Signal()
	return
}

// check if item already exists in queue (or it has been into queue)
func (q *Queue) ItemExists(item QueueItem) bool {
	q.cond.L.Lock()
	defer q.cond.L.Unlock()
	return q.idExists(item.Id())
}

func (q *Queue) IdExists(id interface{}) bool {
	q.cond.L.Lock()
	defer q.cond.L.Unlock()
	return q.idExists(id)
}

func (q *Queue) idExists(id interface{}) bool {
	if _, ok := q.history[id]; ok {
		return true
	} else {
		return false
	}
}

// Enqueue puts item in queue only if it hasn't already been in queue
func (q *Queue) EnqueueUnique(item QueueItem) (added bool, err error) {
	q.cond.L.Lock()
	defer q.cond.L.Unlock()
	if !q.idExists(item.Id()) {
		err = q.enqueue(item)
		added = true
	}
	return
}

/*
	Clear queue history so the elements can be EnqueueUnique again
*/
func (q *Queue) ClearHistory() {
	q.cond.L.Lock()
	defer q.cond.L.Unlock()
	q.history = nil
	q.history = make(map[interface{}]struct{}, 0)
}

func (q *Queue) RemoveFromHistory(element interface{}) {
	q.cond.L.Lock()
	defer q.cond.L.Unlock()
	delete(q.history, element)
}

// Dequeue takes an item from the queue. If queue is empty
// then should block waiting for at least one item.
func (q *Queue) Dequeue() (item QueueItem) {
	q.cond.L.Lock()
	defer q.cond.L.Unlock()
	var x interface{}
	for {
		x = heap.Pop(q.items)
		if x == nil {
			q.cond.Wait()
		} else {
			break
		}
	}
	item = x.(QueueItem)
	return
}

// Safely changes enqueued items limit. When limit is set
// to 0, then queue is unlimited.
func (q *Queue) ChangeLimit(newLimit int) {
	q.cond.L.Lock()
	defer q.cond.L.Unlock()
	q.Limit = newLimit
}

// Len returns number of enqueued elemnents.
func (q *Queue) Len() int {
	return q.items.Len()
}

// IsEmpty returns true if queue is empty.
func (q *Queue) IsEmpty() bool {
	return q.Len() == 0
}

type sorter []QueueItem

func (s *sorter) Push(i interface{}) {
	item, ok := i.(QueueItem)
	if !ok {
		return
	}
	*s = append((*s)[:], item)
}

func (s *sorter) Pop() (x interface{}) {
	if s.Len() > 0 {
		l := s.Len() - 1
		x = (*s)[l]
		(*s)[l] = nil
		*s = (*s)[:l]
	}
	return
}

func (s *sorter) Len() int {
	return len((*s)[:])
}

func (s *sorter) Less(i, j int) bool {
	return (*s)[i].Less((*s)[j])
}

func (s *sorter) Swap(i, j int) {
	if s.Len() > 0 {
		(*s)[i], (*s)[j] = (*s)[j], (*s)[i]
	}
}
<|endoftext|>


<commit_before>package rw

import (
	"bytes"
	"io"
	"strings"
)

// PrefixedWriter TODO
type PrefixedWriter struct {
	W      io.Writer     // underlying writer
	Prefix func() string // generates string used to prefix each line

	first bool
}

// PrefixWriter TODO
func PrefixWriter(writer io.Writer, prefix func() string) io.Writer {
	return &PrefixedWriter{W: writer, Prefix: prefix}
}

// Write TODO
func (pw *PrefixedWriter) Write(p []byte) (int, error) {
	if !pw.first {
		// Write prefix for the first line.
		if _, err := io.Copy(pw.W, strings.NewReader(pw.Prefix())); err != nil {
			return 0, err
		}
		pw.first = true
	}
	var (
		i int // offset of the begining of a line
		j int // offset of the end of a line before newline characters
		k int // relative offset of a next begining of a line
		n int // width of the newline characters (1 for LF, 2 for CRLF)
	)
	if j, n = indexnl(p); j != -1 {
		var (
			err error
			buf bytes.Buffer
		)
		// If p contains multiple newlines we loop over each of them.
	Loop:
		// Write line.
		if _, err = buf.Write(p[i : j+n]); err != nil {
			return 0, err
		}
		i = j + n
		// Search next newline.
		if k, n = indexnl(p[i:]); k != -1 {
			// Write prefix for the next line.
			if _, err = buf.WriteString(pw.Prefix()); err != nil {
				return 0, err
			}
			j = i + k
			goto Loop
		}
		// Write last line if p does not end with a newline.
		if i < len(p) {
			// Write prefix for the last line.
			if _, err = buf.WriteString(pw.Prefix()); err != nil {
				return 0, err
			}
			// Write the last line.
			if _, err = buf.Write(p[i:]); err != nil {
				return 0, err
			}
		}
		n, err := io.Copy(pw.W, &buf)
		return min(int(n), len(p)), err
	}
	return pw.W.Write(p)
}
<commit_msg>Simplify PrefixedWriter.Write<commit_after>package rw

import (
	"bytes"
	"io"
)

// PrefixedWriter TODO
type PrefixedWriter struct {
	W      io.Writer     // underlying writer
	Prefix func() string // generates string used to prefix each line
}

// PrefixWriter TODO
func PrefixWriter(writer io.Writer, prefix func() string) io.Writer {
	return PrefixedWriter{W: writer, Prefix: prefix}
}

// Write TODO
func (pw PrefixedWriter) Write(p []byte) (int, error) {
	var (
		i   int
		err error
		buf bytes.Buffer
	)
	// If p contains multiple newlines we loop over each of them.
	for j, n := indexnl(p); j != -1; j, n = indexnl(p[i:]) {
		j += i
		// Write prefix.
		if _, err = buf.WriteString(pw.Prefix()); err != nil {
			return 0, err
		}
		// Write line.
		if _, err = buf.Write(p[i : j+n]); err != nil {
			return 0, err
		}
		i = j + n
	}
	if i != 0 {
		// Write last line if p does not end with a newline.
		if i < len(p) {
			// Write prefix for the last line.
			if _, err = buf.WriteString(pw.Prefix()); err != nil {
				return 0, err
			}
			// Write the last line.
			if _, err = buf.Write(p[i:]); err != nil {
				return 0, err
			}
		}
		n, err := io.Copy(pw.W, &buf)
		return min(int(n), len(p)), err
	}
	return pw.W.Write(p)
}
<|endoftext|>


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

package lease

import (
	"fmt"
	"io"
	"log"
	"os"

	"github.com/jacobsa/gcloud/syncutil"
)

// A read-write wrapper around a file. Unlike a read lease, this cannot be
// revoked.
//
// All methods are safe for concurrent access.
type ReadWriteLease interface {
	// Methods with semantics matching *os.File.
	io.ReadWriteSeeker
	io.ReaderAt
	io.WriterAt
	Truncate(size int64) (err error)

	// Return the current size of the underlying file.
	Size() (size int64, err error)

	// Downgrade to a read lease, releasing any resources pinned by this lease to
	// the pool that may be revoked, as with any read lease. After downgrading,
	// this lease must not be used again.
	Downgrade() (rl ReadLease)
}

type readWriteLease struct {
	mu syncutil.InvariantMutex

	/////////////////////////
	// Dependencies
	/////////////////////////

	// The leaser that issued this lease.
	leaser *fileLeaser

	// The underlying file, set to nil once downgraded.
	//
	// GUARDED_BY(mu)
	file *os.File

	/////////////////////////
	// Mutable state
	/////////////////////////

	// The cumulative number of bytes we have reported to the leaser using
	// fileLeaser.addReadWriteByteDelta. When the size changes, we report the
	// difference between the new size and this value.
	//
	// GUARDED_BY(mu)
	reportedSize int64

	// Our current view of the file's size, or a negative value if we dirtied the
	// file but then failed to find its size.
	//
	// INVARIANT: If fileSize >= 0, fileSize agrees with file.Stat()
	// INVARIANT: fileSize < 0 || fileSize == reportedSize
	//
	// GUARDED_BY(mu)
	fileSize int64
}

var _ ReadWriteLease = &readWriteLease{}

// size is the size that the leaser has already recorded for us.
func newReadWriteLease(
	leaser *fileLeaser,
	size int64,
	file *os.File) (rwl *readWriteLease) {
	rwl = &readWriteLease{
		leaser:       leaser,
		file:         file,
		reportedSize: size,
	}

	return
}

////////////////////////////////////////////////////////////////////////
// Public interface
////////////////////////////////////////////////////////////////////////

// LOCKS_EXCLUDED(rwl.mu)
func (rwl *readWriteLease) Read(p []byte) (n int, err error) {
	rwl.mu.Lock()
	defer rwl.mu.Unlock()

	n, err = rwl.file.Read(p)
	return
}

// LOCKS_EXCLUDED(rwl.mu)
func (rwl *readWriteLease) Write(p []byte) (n int, err error) {
	rwl.mu.Lock()
	defer rwl.mu.Unlock()

	// Ensure that we reconcile our size when we're done.
	defer rwl.reconcileSize()

	// Call through.
	n, err = rwl.file.Write(p)

	return
}

// LOCKS_EXCLUDED(rwl.mu)
func (rwl *readWriteLease) Seek(
	offset int64,
	whence int) (off int64, err error) {
	rwl.mu.Lock()
	defer rwl.mu.Unlock()

	off, err = rwl.file.Seek(offset, whence)
	return
}

// LOCKS_EXCLUDED(rwl.mu)
func (rwl *readWriteLease) ReadAt(p []byte, off int64) (n int, err error) {
	rwl.mu.Lock()
	defer rwl.mu.Unlock()

	n, err = rwl.file.ReadAt(p, off)
	return
}

// LOCKS_EXCLUDED(rwl.mu)
func (rwl *readWriteLease) WriteAt(p []byte, off int64) (n int, err error) {
	rwl.mu.Lock()
	defer rwl.mu.Unlock()

	// Ensure that we reconcile our size when we're done.
	defer rwl.reconcileSize()

	// Call through.
	n, err = rwl.file.WriteAt(p, off)

	return
}

// LOCKS_EXCLUDED(rwl.mu)
func (rwl *readWriteLease) Truncate(size int64) (err error) {
	rwl.mu.Lock()
	defer rwl.mu.Unlock()

	// Ensure that we reconcile our size when we're done.
	defer rwl.reconcileSize()

	// Call through.
	err = rwl.file.Truncate(size)

	return
}

// LOCKS_EXCLUDED(rwl.mu)
func (rwl *readWriteLease) Size() (size int64, err error) {
	rwl.mu.Lock()
	defer rwl.mu.Unlock()

	size, err = rwl.sizeLocked()
	return
}

// LOCKS_EXCLUDED(rwl.mu)
func (rwl *readWriteLease) Downgrade() (rl ReadLease) {
	rwl.mu.Lock()
	defer rwl.mu.Unlock()

	// Ensure that we will crash if used again.
	defer func() {
		rwl.file = nil
	}()

	// On error, log an error then return a read lease that looks like it was
	// born revoked.
	var err error
	defer func() {
		if err != nil {
			log.Printf("Error downgrading: %v", err)
			rl = &alwaysRevokedReadLease{}
		}
	}()

	// Find the current size under the lock.
	size, err := rwl.sizeLocked()
	if err != nil {
		err = fmt.Errorf("sizeLocked: %v", err)
		return
	}

	// Call the leaser.
	rl = rwl.leaser.downgrade(size, rwl.file)

	return
}

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

// LOCKS_REQUIRED(rwl.mu)
func (rwl *readWriteLease) sizeLocked() (size int64, err error) {
	// Stat the file to get its size.
	fi, err := rwl.file.Stat()
	if err != nil {
		err = fmt.Errorf("Stat: %v", err)
		return
	}

	size = fi.Size()
	return
}

// Notify the leaser if our size has changed. Log errors when we fail to find
// our size.
//
// LOCKS_REQUIRED(rwl.mu)
// LOCKS_EXCLUDED(rwl.leaser.mu)
func (rwl *readWriteLease) reconcileSize() {
	var err error

	// Find our size.
	size, err := rwl.sizeLocked()
	if err != nil {
		log.Println("Error getting size for reconciliation:", err)
		return
	}

	// Let the leaser know about any change.
	delta := size - rwl.reportedSize
	if delta != 0 {
		rwl.leaser.addReadWriteByteDelta(delta)
		rwl.reportedSize = size
	}
}

////////////////////////////////////////////////////////////////////////
// alwaysRevokedReadLease
////////////////////////////////////////////////////////////////////////

type alwaysRevokedReadLease struct {
	size int64
}

func (rl *alwaysRevokedReadLease) Read(p []byte) (n int, err error) {
	err = &RevokedError{}
	return
}

func (rl *alwaysRevokedReadLease) Seek(
	offset int64,
	whence int) (off int64, err error) {
	err = &RevokedError{}
	return
}

func (rl *alwaysRevokedReadLease) ReadAt(
	p []byte, off int64) (n int, err error) {
	err = &RevokedError{}
	return
}

func (rl *alwaysRevokedReadLease) Size() (size int64) {
	size = rl.size
	return
}

func (rl *alwaysRevokedReadLease) Revoked() (revoked bool) {
	revoked = true
	return
}

func (rl *alwaysRevokedReadLease) Upgrade() (rwl ReadWriteLease, err error) {
	err = &RevokedError{}
	return
}

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

package lease

import (
	"fmt"
	"io"
	"log"
	"os"

	"github.com/jacobsa/gcloud/syncutil"
)

// A read-write wrapper around a file. Unlike a read lease, this cannot be
// revoked.
//
// All methods are safe for concurrent access.
type ReadWriteLease interface {
	// Methods with semantics matching *os.File.
	io.ReadWriteSeeker
	io.ReaderAt
	io.WriterAt
	Truncate(size int64) (err error)

	// Return the current size of the underlying file.
	Size() (size int64, err error)

	// Downgrade to a read lease, releasing any resources pinned by this lease to
	// the pool that may be revoked, as with any read lease. After downgrading,
	// this lease must not be used again.
	Downgrade() (rl ReadLease)
}

type readWriteLease struct {
	mu syncutil.InvariantMutex

	/////////////////////////
	// Dependencies
	/////////////////////////

	// The leaser that issued this lease.
	leaser *fileLeaser

	// The underlying file, set to nil once downgraded.
	//
	// GUARDED_BY(mu)
	file *os.File

	/////////////////////////
	// Mutable state
	/////////////////////////

	// The cumulative number of bytes we have reported to the leaser using
	// fileLeaser.addReadWriteByteDelta. When the size changes, we report the
	// difference between the new size and this value.
	//
	// GUARDED_BY(mu)
	reportedSize int64

	// Our current view of the file's size, or a negative value if we dirtied the
	// file but then failed to find its size.
	//
	// INVARIANT: If fileSize >= 0, fileSize agrees with file.Stat()
	// INVARIANT: fileSize < 0 || fileSize == reportedSize
	//
	// GUARDED_BY(mu)
	fileSize int64
}

var _ ReadWriteLease = &readWriteLease{}

// size is the size that the leaser has already recorded for us.
func newReadWriteLease(
	leaser *fileLeaser,
	size int64,
	file *os.File) (rwl *readWriteLease) {
	rwl = &readWriteLease{
		leaser:       leaser,
		file:         file,
		reportedSize: size,
	}

	rwl.mu = syncutil.NewInvariantMutex(rwl.checkInvariants)

	return
}

////////////////////////////////////////////////////////////////////////
// Public interface
////////////////////////////////////////////////////////////////////////

// LOCKS_EXCLUDED(rwl.mu)
func (rwl *readWriteLease) Read(p []byte) (n int, err error) {
	rwl.mu.Lock()
	defer rwl.mu.Unlock()

	n, err = rwl.file.Read(p)
	return
}

// LOCKS_EXCLUDED(rwl.mu)
func (rwl *readWriteLease) Write(p []byte) (n int, err error) {
	rwl.mu.Lock()
	defer rwl.mu.Unlock()

	// Ensure that we reconcile our size when we're done.
	defer rwl.reconcileSize()

	// Call through.
	n, err = rwl.file.Write(p)

	return
}

// LOCKS_EXCLUDED(rwl.mu)
func (rwl *readWriteLease) Seek(
	offset int64,
	whence int) (off int64, err error) {
	rwl.mu.Lock()
	defer rwl.mu.Unlock()

	off, err = rwl.file.Seek(offset, whence)
	return
}

// LOCKS_EXCLUDED(rwl.mu)
func (rwl *readWriteLease) ReadAt(p []byte, off int64) (n int, err error) {
	rwl.mu.Lock()
	defer rwl.mu.Unlock()

	n, err = rwl.file.ReadAt(p, off)
	return
}

// LOCKS_EXCLUDED(rwl.mu)
func (rwl *readWriteLease) WriteAt(p []byte, off int64) (n int, err error) {
	rwl.mu.Lock()
	defer rwl.mu.Unlock()

	// Ensure that we reconcile our size when we're done.
	defer rwl.reconcileSize()

	// Call through.
	n, err = rwl.file.WriteAt(p, off)

	return
}

// LOCKS_EXCLUDED(rwl.mu)
func (rwl *readWriteLease) Truncate(size int64) (err error) {
	rwl.mu.Lock()
	defer rwl.mu.Unlock()

	// Ensure that we reconcile our size when we're done.
	defer rwl.reconcileSize()

	// Call through.
	err = rwl.file.Truncate(size)

	return
}

// LOCKS_EXCLUDED(rwl.mu)
func (rwl *readWriteLease) Size() (size int64, err error) {
	rwl.mu.Lock()
	defer rwl.mu.Unlock()

	size, err = rwl.sizeLocked()
	return
}

// LOCKS_EXCLUDED(rwl.mu)
func (rwl *readWriteLease) Downgrade() (rl ReadLease) {
	rwl.mu.Lock()
	defer rwl.mu.Unlock()

	// Ensure that we will crash if used again.
	defer func() {
		rwl.file = nil
	}()

	// On error, log an error then return a read lease that looks like it was
	// born revoked.
	var err error
	defer func() {
		if err != nil {
			log.Printf("Error downgrading: %v", err)
			rl = &alwaysRevokedReadLease{}
		}
	}()

	// Find the current size under the lock.
	size, err := rwl.sizeLocked()
	if err != nil {
		err = fmt.Errorf("sizeLocked: %v", err)
		return
	}

	// Call the leaser.
	rl = rwl.leaser.downgrade(size, rwl.file)

	return
}

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

// LOCKS_REQUIRED(rwl.mu)
func (rwl *readWriteLease) checkInvariants() {
	// Have we been dowgraded?
	if rwl.file == nil {
		return
	}

	// INVARIANT: If fileSize >= 0, fileSize agrees with file.Stat()
	if rwl.fileSize >= 0 {
		fi, err := rwl.file.Stat()
		if err != nil {
			panic(fmt.Sprintf("Failed to stat file: %v", err))
		}

		if rwl.fileSize != fi.Size() {
			panic(fmt.Sprintf("Size mismatch: %v vs. %v", rwl.fileSize, fi.Size()))
		}
	}

	// INVARIANT: fileSize < 0 || fileSize == reportedSize
	if !(rwl.fileSize < 0 || rwl.fileSize == rwl.reportedSize) {
		panic(fmt.Sprintf("Size mismatch: %v vs. %v", rwl.fileSize, rwl.reportedSize))
	}
}

// LOCKS_REQUIRED(rwl.mu)
func (rwl *readWriteLease) sizeLocked() (size int64, err error) {
	// Stat the file to get its size.
	fi, err := rwl.file.Stat()
	if err != nil {
		err = fmt.Errorf("Stat: %v", err)
		return
	}

	size = fi.Size()
	return
}

// Notify the leaser if our size has changed. Log errors when we fail to find
// our size.
//
// LOCKS_REQUIRED(rwl.mu)
// LOCKS_EXCLUDED(rwl.leaser.mu)
func (rwl *readWriteLease) reconcileSize() {
	var err error

	// Find our size.
	size, err := rwl.sizeLocked()
	if err != nil {
		log.Println("Error getting size for reconciliation:", err)
		return
	}

	// Let the leaser know about any change.
	delta := size - rwl.reportedSize
	if delta != 0 {
		rwl.leaser.addReadWriteByteDelta(delta)
		rwl.reportedSize = size
	}
}

////////////////////////////////////////////////////////////////////////
// alwaysRevokedReadLease
////////////////////////////////////////////////////////////////////////

type alwaysRevokedReadLease struct {
	size int64
}

func (rl *alwaysRevokedReadLease) Read(p []byte) (n int, err error) {
	err = &RevokedError{}
	return
}

func (rl *alwaysRevokedReadLease) Seek(
	offset int64,
	whence int) (off int64, err error) {
	err = &RevokedError{}
	return
}

func (rl *alwaysRevokedReadLease) ReadAt(
	p []byte, off int64) (n int, err error) {
	err = &RevokedError{}
	return
}

func (rl *alwaysRevokedReadLease) Size() (size int64) {
	size = rl.size
	return
}

func (rl *alwaysRevokedReadLease) Revoked() (revoked bool) {
	revoked = true
	return
}

func (rl *alwaysRevokedReadLease) Upgrade() (rwl ReadWriteLease, err error) {
	err = &RevokedError{}
	return
}

func (rl *alwaysRevokedReadLease) Revoke() {
}
<|endoftext|>


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

package piazza

import (
	"fmt"
	"testing"
	"time"
)

const kafkaHost = "localhost:9092"

var OffsetNewest int64

var kafka *Kafka

func doReads(t *testing.T, numReads *int) {
	c, err := kafka.NewConsumer()
	if err != nil {
		t.Fatal(err)
	}

	defer func() {
		if err := c.Close(); err != nil {
			t.Fatal(err)
		}
	}()

	partitionConsumer, err := c.ConsumePartition("test3", 0, OffsetNewest)
	if err != nil {
		panic(err)
	}

	defer func() {
		if err := partitionConsumer.Close(); err != nil {
			t.Fatal(err)
		}
	}()

	for {
		msg := <-partitionConsumer.Messages()
		t.Logf("Consumed: offset:%d  value:%v", msg.Offset, string(msg.Value))
		*numReads++
	}

	//t.Logf("Reader done: %d", *numReads)
}

func doWrites(t *testing.T, id int, count int) {

	p, err := kafka.NewProducer()
	if err != nil {
		t.Fatal(err)
	}

	defer func() {
		if err := p.Close(); err != nil {
			t.Fatal(err)
		}
	}()

	// TODO: handle "err := <-w.Errors():"

	for n := 0; n < count; n++ {
		p.Input() <- NewMessage("test3", fmt.Sprintf("mssg %d from %d", n, id))
	}

	t.Logf("Writer done: %d", count)
}

func TestKafka(t *testing.T) {
	kafka = &Kafka{host: kafkaHost}

	var numReads1, numReads2 int

	go doReads(t, &numReads1)
	go doReads(t, &numReads2)

	n := 3
	go doWrites(t, 1, n)
	go doWrites(t, 2, n)

	time.Sleep(1 * time.Second)

	t.Log(numReads1, "---")
	t.Log(numReads2, "---")

	if numReads1 != n*2 {
		t.Fatalf("read1 count was %d, expected %d", numReads1, n*2)
	}
	if numReads2 != n*2 {
		t.Fatalf("read2 count was %d, expected %d", numReads2, n*2)
	}
}
<commit_msg>randomize topic name<commit_after>// Copyright 2016, RadiantBlue Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package piazza

import (
	"fmt"
	"log"
	"math/rand"
	"testing"
	"time"
)

const kafkaHost = "localhost:9092"

var topicName = "test.topic."

var OffsetNewest int64

var kafka *Kafka

func doReads(t *testing.T, numReads *int) {
	c, err := kafka.NewConsumer()
	if err != nil {
		t.Fatal(err)
	}

	defer func() {
		if err := c.Close(); err != nil {
			t.Fatal(err)
		}
	}()

	partitionConsumer, err := c.ConsumePartition(topicName, 0, OffsetNewest)
	if err != nil {
		panic(err)
	}

	defer func() {
		if err := partitionConsumer.Close(); err != nil {
			t.Fatal(err)
		}
	}()

	for {
		msg := <-partitionConsumer.Messages()
		t.Logf("Consumed: offset:%d  value:%v", msg.Offset, string(msg.Value))
		*numReads++
	}

	//t.Logf("Reader done: %d", *numReads)
}

func doWrites(t *testing.T, id int, count int) {

	p, err := kafka.NewProducer()
	if err != nil {
		t.Fatal(err)
	}

	defer func() {
		if err := p.Close(); err != nil {
			t.Fatal(err)
		}
	}()

	// TODO: handle "err := <-w.Errors():"

	for n := 0; n < count; n++ {
		p.Input() <- NewMessage(topicName, fmt.Sprintf("mssg %d from %d", n, id))
	}

	t.Logf("Writer done: %d", count)
}

func TestKafka(t *testing.T) {
	kafka = &Kafka{host: kafkaHost}

	rand.Seed(int64(time.Now().Nanosecond()))
	topicName += fmt.Sprintf("%x", rand.Uint32())
	log.Printf("topic: %s", topicName)

	var numReads1, numReads2 int

	go doReads(t, &numReads1)
	go doReads(t, &numReads2)

	n := 3
	go doWrites(t, 1, n)
	go doWrites(t, 2, n)

	time.Sleep(1 * time.Second)

	t.Log(numReads1, "---")
	t.Log(numReads2, "---")

	if numReads1 != n*2 {
		t.Fatalf("read1 count was %d, expected %d", numReads1, n*2)
	}
	if numReads2 != n*2 {
		t.Fatalf("read2 count was %d, expected %d", numReads2, n*2)
	}
}
<|endoftext|>


<commit_before>
// Package that provides chronobiology functions to analyse time series data
package chronobiology

import (
    "time"
    "errors"
    "math"
)

/* BEGIN INTERNAL FUNCTIONS */

// Used to truncate a float64 value
func round(value float64) float64 {
    return math.Floor(value + .5)
}

// Used to truncate a float64 value to a particular precision
func roundPlus(value float64, places int) (float64) {
    shift := math.Pow(10, float64(places))
    return round(value * shift) / shift;
}

// Calculates the average of a float64 slice
func average(data []float64) (float64) {
    var average float64
    if len(data) == 0 {
      return average
    }
    for index := 0; index < len(data); index++ {
        average += data[index]
    }
    return average / float64(len(data))
}

// Searches for a value in a slice and returns its position
func findPosition(value int, data []int) (int) {
    if len(data) == 0 {
        return -1
    }
    for index := 0; index < len(data); index++ {
        if data[index] == value {
            return index
        }
    }
    return -1
}

// Finds the max value in a slice and returns its position
func findMaxPosition(data []int) (int) {
    if len(data) == 0 {
        return -1
    }
    var position int
    max := data[0]

    for index := 0; index < len(data); index++ {
        if data[index] > max {
            max = data[index]
            position = index
        }
    }
    return position
}

// Calculates the difference between two time.Time in seconds
func secondsTo(date1 time.Time, date2 time.Time) (int) {

    if date1.Equal(date2) || date1.After(date2) {
        return 0
    }

    // Get the number of seconds elapsed since 01/01/1970
    seconds1 := date1.Unix()
    seconds2 := date2.Unix()

    // Calculate the difference in seconds
    seconds := seconds2-seconds1

    // Return the seconds as int instead of int64
    return int(seconds)
}

var EPSILON float64 = 0.00000001

func floatEquals(a, b float64) bool {
    if ((a - b) < EPSILON && (b - a) < EPSILON) {
        return true
    }
    return false
}

// Function used to decrease the epoch
func decrease(dateTime []time.Time, data []float64, currentEpoch int, newEpoch int) (newDateTime []time.Time, newData[]float64) {

    startDateTime := dateTime[0]
    // The start time must be the same start time of the current recorded data
    startDateTime = startDateTime.Add(-(time.Duration(currentEpoch) * time.Second))

    for index1 := 0; index1 < len(dateTime); index1++ {
        // To each data "row", split it to X new "rows"
        for index2 := 0; index2 < currentEpoch/newEpoch; index2++ {
            startDateTime = startDateTime.Add(time.Duration(newEpoch) * time.Second)
            newDateTime = append(newDateTime, startDateTime)
            newData     = append(newData, data[index1])
        }
    }

    return
}

// Function used to increase the epoch
func increase(dateTime []time.Time, data []float64, currentEpoch int, newEpoch int) (newDateTime []time.Time, newData[]float64) {

    var tempEpoch int
    var tempData float64

    startDateTime := dateTime[0]
    // The start time must be the same start time of the current recorded data
    startDateTime = startDateTime.Add(-(time.Duration(currentEpoch) * time.Second))

    for index1 := 0; index1 < len(dateTime); index1++ {
        tempEpoch += currentEpoch
        tempData  += data[index1]

        if tempEpoch >= newEpoch {
            startDateTime = startDateTime.Add(time.Duration(newEpoch) * time.Second)
            newDateTime = append(newDateTime, startDateTime)

            tempData    = tempData / (float64(newEpoch)/float64(currentEpoch))
            tempData    = roundPlus(tempData, 4)
            newData     = append(newData, tempData)

            tempEpoch = 0
            tempData  = 0.0
        }
    }

    return
}

/* END INTERNAL FUNCTIONS */

// Function that finds the highest activity average of the followed X hours (defined by parameter)
func HigherActivity(hours int, dateTime []time.Time, data []float64) (higherActivity float64, onsetHigherActivity time.Time, err error) {

    // Check the parameters
    if hours == 0 {
        err = errors.New("InvalidHours")
        return
    }
    if len(dateTime) == 0 || len(data) == 0 {
        err = errors.New("Empty")
        return
    }
    if len(dateTime) != len(data) {
        err = errors.New("DifferentSize")
        return
    }
    if dateTime[0].Add(time.Duration(hours) * time.Hour).After( dateTime[len(dateTime)-1] ) {
        err = errors.New("HoursHigher")
        return
    }

    for index := 0; index < len(dateTime); index++ {

        startDateTime := dateTime[index]
        finalDateTime := startDateTime.Add(time.Duration(hours) * time.Hour)
        tempDateTime  := startDateTime

        if finalDateTime.After( dateTime[len(dateTime)-1] ) {
            break
        }

        currentActivity := 0.0
        tempIndex := index
        count := 0

        for tempDateTime.Before(finalDateTime) {
            currentActivity += data[tempIndex]
            count += 1
            tempIndex += 1

            if tempIndex >= len(dateTime) {
                break
            }

            tempDateTime = dateTime[tempIndex]
        }

        currentActivity /= float64(count)

        if currentActivity > higherActivity || floatEquals(higherActivity, 0.0) {
            higherActivity = roundPlus(currentActivity, 4)
            onsetHigherActivity = startDateTime
        }
    }

    return
}

// Function that finds the lowest activity average of the followed X hours (defined by parameter)
func LowerActivity(hours int, dateTime []time.Time, data []float64) (lowerActivity float64, onsetLowerActivity time.Time, err error) {

      // Check the parameters
      if hours == 0 {
          err = errors.New("InvalidHours")
          return
      }
      if len(dateTime) == 0 || len(data) == 0 {
          err = errors.New("Empty")
          return
      }
      if len(dateTime) != len(data) {
          err = errors.New("DifferentSize")
          return
      }
      if dateTime[0].Add(time.Duration(hours) * time.Hour).After( dateTime[len(dateTime)-1] ) {
          err = errors.New("HoursHigher")
          return
      }

      firstTime := true

      for index := 0; index < len(dateTime); index++ {

          startDateTime := dateTime[index]
          finalDateTime := startDateTime.Add(time.Duration(hours) * time.Hour)
          tempDateTime  := startDateTime

          if finalDateTime.After( dateTime[len(dateTime)-1] ) {
              break
          }

          currentActivity := 0.0
          tempIndex := index
          count := 0

          for tempDateTime.Before(finalDateTime) {
              currentActivity += data[tempIndex]
              count += 1
              tempIndex += 1

              if tempIndex >= len(dateTime) {
                  break
              }

              tempDateTime = dateTime[tempIndex]
          }

          currentActivity /= float64(count)

          if currentActivity < lowerActivity || firstTime == true {
              lowerActivity = roundPlus(currentActivity, 4)
              onsetLowerActivity = startDateTime
              firstTime = false
          }
      }

      return
}

// Function that finds the highest activity average of the followed 10 hours
func M10(dateTime []time.Time, data []float64) (higherActivity float64, onsetHigherActivity time.Time, err error) {
    higherActivity, onsetHigherActivity, err = HigherActivity(10, dateTime, data)
    return
}

// Function that finds the lowest activity average of the following 5 hours
func L5(dateTime []time.Time, data []float64) (lowerActivity float64, onsetLowerActivity time.Time, err error) {
    lowerActivity, onsetLowerActivity, err = LowerActivity(5, dateTime, data)
    return
}

// Function that calculates the relative amplitude based on the formula (M10-L5)/(M10+L5)
func RelativeAmplitude(highestAverage float64, lowestAverage float64) (RA float64, err error) {
    if( highestAverage == 0.0 && lowestAverage == 0.0 ) {
        err = errors.New("NullValues")
        return
    }

    RA = (highestAverage-lowestAverage) / (highestAverage+lowestAverage)
    RA = roundPlus(RA, 4)
    return
}

// Function that calculates the intradaily variability
func IntradailyVariability(dateTime []time.Time, data []float64) (iv []float64, err error) {

    if len(dateTime) == 0 || len(data) == 0 {
        err = errors.New("Empty")
        return
    }
    if len(dateTime) != len(data) {
        err = errors.New("DifferentSize")
        return
    }
    if secondsTo(dateTime[0], dateTime[len(dateTime)-1]) < (2*60*60) {
        err = errors.New("LessThan2Hours")
    }

    // The zero position is allocated to store the average value of the iv vector
    iv = append(iv, 0.0)

    for mainIndex := 1; mainIndex <= 60; mainIndex++ {

        _, tempData, err := ConvertDataBasedOnEpoch(dateTime, data, (mainIndex*60))

        if err != nil {
            err = errors.New("ConvertDataBasedOnEpoch error")
            iv = nil
            return iv, err
        }

        if len(tempData) > 0 {

            average := average(tempData)

            // Calculates the numerator
            var numerator float64
            for index := 1; index < len(tempData); index++ {
                tempValue := tempData[index] - tempData[index-1]
                numerator += math.Pow(tempValue, 2)
            }
            numerator = numerator * float64(len(tempData))

            // Calculates the denominator
            var denominator float64
            for index := 0; index < len(tempData); index++ {
                tempValue := average - tempData[index]
                denominator += math.Pow(tempValue, 2)
            }
            denominator = denominator * (float64(len(tempData)) - 1.0)

            result := roundPlus((numerator/denominator), 4)
            iv = append(iv, result)

        } else {
            iv = append(iv, 0.0)
        }
    }

    // Calculates the IV average
    var average float64
    for index := 1; index < len(iv); index++ {
        average += iv[index]
    }
    average = average / float64(len(iv)-1)
    iv[0] = average

    return
}

// Function that finds the epoch of a time series (seconds)
func FindEpoch(dateTime []time.Time) (epoch int) {

    if len(dateTime) == 0 {
        return
    }

    var count []int
    var epochs []int

    for index := 1; index < len(dateTime); index++ {

        seconds := secondsTo(dateTime[index-1], dateTime[index])

        position := findPosition(seconds, epochs)
        if position > -1 {
            count[position] += 1
        }else {
            epochs = append(epochs, seconds)
            count  = append(count, 1)
        }
    }

    maxPos := findMaxPosition(count)
    epoch = epochs[maxPos]

    return
}

// Convert the data and dateTime slices to the new epoch passed by parameter
func ConvertDataBasedOnEpoch(dateTime []time.Time, data []float64, newEpoch int) (newDateTime []time.Time, newData []float64, err error) {

    // Check the parameters
    if len(dateTime) == 0 || len(data) == 0 {
        err = errors.New("Empty")
        return
    }
    if len(dateTime) != len(data) {
        err = errors.New("DifferentSize")
        return
    }
    if newEpoch == 0 {
        err = errors.New("InvalidEpoch")
        return
    }

    currentEpoch  := FindEpoch(dateTime)

    // Could not find the epoch
    if currentEpoch == 0 {
        err = errors.New("InvalidEpoch")
        return
    }
    if newEpoch == currentEpoch {
        return dateTime, data, nil
    }

    // If the new Epoch is not divisible or multipliable by the currentEpoch
    // It needs to be decreased to 1 second to then increase to the newEpoch
    if (newEpoch > currentEpoch && newEpoch % currentEpoch != 0) ||
       (currentEpoch > newEpoch && currentEpoch % newEpoch != 0)  {

        // Decrease to 1 second
        dateTime, data = decrease(dateTime, data, currentEpoch, 1);

        // Increase to the newEpoch
        newDateTime, newData = increase(dateTime, data, 1, newEpoch);

    } else {
        // Increase
        if newEpoch > currentEpoch {
            newDateTime, newData = increase(dateTime, data, currentEpoch, newEpoch);

        // Decrease
        } else {
            newDateTime, newData = decrease(dateTime, data, currentEpoch, newEpoch);
        }
    }

    return
}
<commit_msg>Added function FilterDataByDateTime<commit_after>
// Package that provides chronobiology functions to analyse time series data
package chronobiology

import (
    "time"
    "errors"
    "math"
)

/* BEGIN INTERNAL FUNCTIONS */

// Used to truncate a float64 value
func round(value float64) float64 {
    return math.Floor(value + .5)
}

// Used to truncate a float64 value to a particular precision
func roundPlus(value float64, places int) (float64) {
    shift := math.Pow(10, float64(places))
    return round(value * shift) / shift;
}

// Calculates the average of a float64 slice
func average(data []float64) (float64) {
    var average float64
    if len(data) == 0 {
      return average
    }
    for index := 0; index < len(data); index++ {
        average += data[index]
    }
    return average / float64(len(data))
}

// Searches for a value in a slice and returns its position
func findPosition(value int, data []int) (int) {
    if len(data) == 0 {
        return -1
    }
    for index := 0; index < len(data); index++ {
        if data[index] == value {
            return index
        }
    }
    return -1
}

// Finds the max value in a slice and returns its position
func findMaxPosition(data []int) (int) {
    if len(data) == 0 {
        return -1
    }
    var position int
    max := data[0]

    for index := 0; index < len(data); index++ {
        if data[index] > max {
            max = data[index]
            position = index
        }
    }
    return position
}

// Calculates the difference between two time.Time in seconds
func secondsTo(date1 time.Time, date2 time.Time) (int) {

    if date1.Equal(date2) || date1.After(date2) {
        return 0
    }

    // Get the number of seconds elapsed since 01/01/1970
    seconds1 := date1.Unix()
    seconds2 := date2.Unix()

    // Calculate the difference in seconds
    seconds := seconds2-seconds1

    // Return the seconds as int instead of int64
    return int(seconds)
}

func floatEquals(a, b float64) bool {
    var epsilon float64 = 0.00000001
    if ((a - b) < epsilon && (b - a) < epsilon) {
        return true
    }
    return false
}

// Function used to decrease the epoch
func decrease(dateTime []time.Time, data []float64, currentEpoch int, newEpoch int) (newDateTime []time.Time, newData[]float64) {

    startDateTime := dateTime[0]
    // The start time must be the same start time of the current recorded data
    startDateTime = startDateTime.Add(-(time.Duration(currentEpoch) * time.Second))

    for index1 := 0; index1 < len(dateTime); index1++ {
        // To each data "row", split it to X new "rows"
        for index2 := 0; index2 < currentEpoch/newEpoch; index2++ {
            startDateTime = startDateTime.Add(time.Duration(newEpoch) * time.Second)
            newDateTime = append(newDateTime, startDateTime)
            newData     = append(newData, data[index1])
        }
    }

    return
}

// Function used to increase the epoch
func increase(dateTime []time.Time, data []float64, currentEpoch int, newEpoch int) (newDateTime []time.Time, newData[]float64) {

    var tempEpoch int
    var tempData float64

    startDateTime := dateTime[0]
    // The start time must be the same start time of the current recorded data
    startDateTime = startDateTime.Add(-(time.Duration(currentEpoch) * time.Second))

    for index1 := 0; index1 < len(dateTime); index1++ {
        tempEpoch += currentEpoch
        tempData  += data[index1]

        if tempEpoch >= newEpoch {
            startDateTime = startDateTime.Add(time.Duration(newEpoch) * time.Second)
            newDateTime = append(newDateTime, startDateTime)

            tempData    = tempData / (float64(newEpoch)/float64(currentEpoch))
            tempData    = roundPlus(tempData, 4)
            newData     = append(newData, tempData)

            tempEpoch = 0
            tempData  = 0.0
        }
    }

    return
}

/* END INTERNAL FUNCTIONS */

// Function that finds the highest activity average of the followed X hours (defined by parameter)
func HigherActivity(hours int, dateTime []time.Time, data []float64) (higherActivity float64, onsetHigherActivity time.Time, err error) {

    // Check the parameters
    if hours == 0 {
        err = errors.New("InvalidHours")
        return
    }
    if len(dateTime) == 0 || len(data) == 0 {
        err = errors.New("Empty")
        return
    }
    if len(dateTime) != len(data) {
        err = errors.New("DifferentSize")
        return
    }
    if dateTime[0].Add(time.Duration(hours) * time.Hour).After( dateTime[len(dateTime)-1] ) {
        err = errors.New("HoursHigher")
        return
    }

    for index := 0; index < len(dateTime); index++ {

        startDateTime := dateTime[index]
        finalDateTime := startDateTime.Add(time.Duration(hours) * time.Hour)
        tempDateTime  := startDateTime

        if finalDateTime.After( dateTime[len(dateTime)-1] ) {
            break
        }

        currentActivity := 0.0
        tempIndex := index
        count := 0

        for tempDateTime.Before(finalDateTime) {
            currentActivity += data[tempIndex]
            count += 1
            tempIndex += 1

            if tempIndex >= len(dateTime) {
                break
            }

            tempDateTime = dateTime[tempIndex]
        }

        currentActivity /= float64(count)

        if currentActivity > higherActivity || floatEquals(higherActivity, 0.0) {
            higherActivity = roundPlus(currentActivity, 4)
            onsetHigherActivity = startDateTime
        }
    }

    return
}

// Function that finds the lowest activity average of the followed X hours (defined by parameter)
func LowerActivity(hours int, dateTime []time.Time, data []float64) (lowerActivity float64, onsetLowerActivity time.Time, err error) {

      // Check the parameters
      if hours == 0 {
          err = errors.New("InvalidHours")
          return
      }
      if len(dateTime) == 0 || len(data) == 0 {
          err = errors.New("Empty")
          return
      }
      if len(dateTime) != len(data) {
          err = errors.New("DifferentSize")
          return
      }
      if dateTime[0].Add(time.Duration(hours) * time.Hour).After( dateTime[len(dateTime)-1] ) {
          err = errors.New("HoursHigher")
          return
      }

      firstTime := true

      for index := 0; index < len(dateTime); index++ {

          startDateTime := dateTime[index]
          finalDateTime := startDateTime.Add(time.Duration(hours) * time.Hour)
          tempDateTime  := startDateTime

          if finalDateTime.After( dateTime[len(dateTime)-1] ) {
              break
          }

          currentActivity := 0.0
          tempIndex := index
          count := 0

          for tempDateTime.Before(finalDateTime) {
              currentActivity += data[tempIndex]
              count += 1
              tempIndex += 1

              if tempIndex >= len(dateTime) {
                  break
              }

              tempDateTime = dateTime[tempIndex]
          }

          currentActivity /= float64(count)

          if currentActivity < lowerActivity || firstTime == true {
              lowerActivity = roundPlus(currentActivity, 4)
              onsetLowerActivity = startDateTime
              firstTime = false
          }
      }

      return
}

// Function that finds the highest activity average of the followed 10 hours
func M10(dateTime []time.Time, data []float64) (higherActivity float64, onsetHigherActivity time.Time, err error) {
    higherActivity, onsetHigherActivity, err = HigherActivity(10, dateTime, data)
    return
}

// Function that finds the lowest activity average of the following 5 hours
func L5(dateTime []time.Time, data []float64) (lowerActivity float64, onsetLowerActivity time.Time, err error) {
    lowerActivity, onsetLowerActivity, err = LowerActivity(5, dateTime, data)
    return
}

// Function that calculates the relative amplitude based on the formula (M10-L5)/(M10+L5)
func RelativeAmplitude(highestAverage float64, lowestAverage float64) (RA float64, err error) {
    if( highestAverage == 0.0 && lowestAverage == 0.0 ) {
        err = errors.New("NullValues")
        return
    }

    RA = (highestAverage-lowestAverage) / (highestAverage+lowestAverage)
    RA = roundPlus(RA, 4)
    return
}

// Function that calculates the intradaily variability
func IntradailyVariability(dateTime []time.Time, data []float64) (iv []float64, err error) {

    if len(dateTime) == 0 || len(data) == 0 {
        err = errors.New("Empty")
        return
    }
    if len(dateTime) != len(data) {
        err = errors.New("DifferentSize")
        return
    }
    if secondsTo(dateTime[0], dateTime[len(dateTime)-1]) < (2*60*60) {
        err = errors.New("LessThan2Hours")
    }

    // The zero position is allocated to store the average value of the iv vector
    iv = append(iv, 0.0)

    for mainIndex := 1; mainIndex <= 60; mainIndex++ {

        _, tempData, err := ConvertDataBasedOnEpoch(dateTime, data, (mainIndex*60))

        if err != nil {
            err = errors.New("ConvertDataBasedOnEpoch error")
            iv = nil
            return iv, err
        }

        if len(tempData) > 0 {

            average := average(tempData)

            // Calculates the numerator
            var numerator float64
            for index := 1; index < len(tempData); index++ {
                tempValue := tempData[index] - tempData[index-1]
                numerator += math.Pow(tempValue, 2)
            }
            numerator = numerator * float64(len(tempData))

            // Calculates the denominator
            var denominator float64
            for index := 0; index < len(tempData); index++ {
                tempValue := average - tempData[index]
                denominator += math.Pow(tempValue, 2)
            }
            denominator = denominator * (float64(len(tempData)) - 1.0)

            result := roundPlus((numerator/denominator), 4)
            iv = append(iv, result)

        } else {
            iv = append(iv, 0.0)
        }
    }

    // Calculates the IV average
    var average float64
    for index := 1; index < len(iv); index++ {
        average += iv[index]
    }
    average = average / float64(len(iv)-1)
    iv[0] = average

    return
}

// Function that finds the epoch of a time series (seconds)
func FindEpoch(dateTime []time.Time) (epoch int) {

    if len(dateTime) == 0 {
        return
    }

    var count []int
    var epochs []int

    for index := 1; index < len(dateTime); index++ {

        seconds := secondsTo(dateTime[index-1], dateTime[index])

        position := findPosition(seconds, epochs)
        if position > -1 {
            count[position] += 1
        }else {
            epochs = append(epochs, seconds)
            count  = append(count, 1)
        }
    }

    maxPos := findMaxPosition(count)
    epoch = epochs[maxPos]

    return
}

// Convert the data and dateTime slices to the new epoch passed by parameter
func ConvertDataBasedOnEpoch(dateTime []time.Time, data []float64, newEpoch int) (newDateTime []time.Time, newData []float64, err error) {

    // Check the parameters
    if len(dateTime) == 0 || len(data) == 0 {
        err = errors.New("Empty")
        return
    }
    if len(dateTime) != len(data) {
        err = errors.New("DifferentSize")
        return
    }
    if newEpoch == 0 {
        err = errors.New("InvalidEpoch")
        return
    }

    currentEpoch  := FindEpoch(dateTime)

    // Could not find the epoch
    if currentEpoch == 0 {
        err = errors.New("InvalidEpoch")
        return
    }
    if newEpoch == currentEpoch {
        return dateTime, data, nil
    }

    // If the new Epoch is not divisible or multipliable by the currentEpoch
    // It needs to be decreased to 1 second to then increase to the newEpoch
    if (newEpoch > currentEpoch && newEpoch % currentEpoch != 0) ||
       (currentEpoch > newEpoch && currentEpoch % newEpoch != 0)  {

        // Decrease to 1 second
        dateTime, data = decrease(dateTime, data, currentEpoch, 1);

        // Increase to the newEpoch
        newDateTime, newData = increase(dateTime, data, 1, newEpoch);

    } else {
        // Increase
        if newEpoch > currentEpoch {
            newDateTime, newData = increase(dateTime, data, currentEpoch, newEpoch);

        // Decrease
        } else {
            newDateTime, newData = decrease(dateTime, data, currentEpoch, newEpoch);
        }
    }

    return
}

// Function created to filter the data based on the startTime and endTime passed as parameter
func FilterDataByDateTime(dateTime []time.Time, data []float64, startTime time.Time, endTime time.Time) (newDateTime []time.Time, newData []float64, err error) {

    // Check the parameters
    if len(dateTime) == 0 || len(data) == 0 {
        err = errors.New("Empty")
        return
    }
    if len(dateTime) != len(data) {
        err = errors.New("DifferentSize")
        return
    }

    // Filter the data based on the startTime and endTime
    for index := 0; index < len(dateTime); index++ {

        if (dateTime[index].After(startTime) || dateTime[index].Equal(startTime)) &&
           (dateTime[index].Before(endTime)  || dateTime[index].Equal(endTime)) {

            newDateTime = append(newDateTime, dateTime[index])
            newData     = append(newData, data[index])
        }
    }

    return
}
<|endoftext|>


<commit_before><commit_msg>Lock container when set state to restarting<commit_after><|endoftext|>