<commit_before>package bbio

// #include <stddef.h>
// #include <sys/types.h>
// #include <linux/i2c-dev.h>
import "C"

import (
	"fmt"
	"os"
	"syscall"
	"unsafe"
)

// I2C is a port of https://github.com/bivab/smbus-cffi/
type I2C struct {
	file    *os.File
	address int
}

// Connects the object to the specified SMBus.
func NewI2C(bus, address int) (*I2C, error) {
	filename := fmt.Sprintf("/dev/i2c-%d", bus)
	file, err := os.OpenFile(filename, os.O_RDWR, 0)
	if err != nil {
		return nil, err
	}

	i2c := &I2C{file: file, address: -1}
	err = i2c.SetAddress(address)
	if err != nil {
		file.Close()
		return nil, err
	}

	return i2c, nil
}

func (i2c *I2C) Address() int {
	return i2c.address
}

func (i2c *I2C) SetAddress(address int) error {
	if address != i2c.address {
		result, _, err := syscall.Syscall(syscall.SYS_IOCTL, i2c.file.Fd(), C.I2C_SLAVE, uintptr(address))
		if result != 0 {
			return err
		}
		i2c.address = address
	}
	return nil
}

// Perform SMBus Read Byte transaction.
func (i2c *I2C) ReadUint8() (uint8, error) {
	result, err := C.i2c_smbus_read_byte(C.int(i2c.file.Fd()))
	if result == -1 {
		return 0, err
	}
	return uint8(result), nil
}

// Perform SMBus Write Byte transaction.
func (i2c *I2C) WriteUint8(value uint8) error {
	result, err := C.i2c_smbus_write_byte(C.int(i2c.file.Fd()), C.__u8(value))
	if result == -1 {
		return err
	}
	return nil
}

// Perform SMBus Read Byte transaction.
func (i2c *I2C) ReadInt8() (int8, error) {
	result, err := C.i2c_smbus_read_byte(C.int(i2c.file.Fd()))
	if result == -1 {
		return 0, err
	}
	if result >= 1<<7 {
		result -= 1 << 8
	}
	return int8(result), nil
}

// Perform SMBus Write Byte transaction.
func (i2c *I2C) WriteInt8(value int8) error {
	return i2c.WriteUint8(uint8(value))
}

// Perform SMBus Read Byte Data transaction.
func (i2c *I2C) ReadUint8Cmd(command uint8) (uint8, error) {
	result, err := C.i2c_smbus_read_byte_data(C.int(i2c.file.Fd()), C.__u8(command))
	if result == -1 {
		return 0, err
	}
	return uint8(result), nil
}

// Perform SMBus Write Byte Data transaction.
func (i2c *I2C) WriteUint8Cmd(command uint8, value uint8) error {
	result, err := C.i2c_smbus_write_byte_data(C.int(i2c.file.Fd()), C.__u8(command), C.__u8(value))
	if result == -1 {
		return err
	}
	return nil
}

// Perform SMBus Read Byte Data transaction.
func (i2c *I2C) ReadInt8Cmd(command uint8) (int8, error) {
	result, err := C.i2c_smbus_read_byte_data(C.int(i2c.file.Fd()), C.__u8(command))
	if result == -1 {
		return 0, err
	}
	if result >= 1<<7 {
		result -= 1 << 8
	}
	return int8(result), nil
}

// Perform SMBus Write Byte Data transaction.
func (i2c *I2C) WriteInt8Cmd(command uint8, value int8) error {
	return i2c.WriteUint8Cmd(command, uint8(value))
}

// Perform SMBus Read Word Data transaction.
func (i2c *I2C) ReadUint16Cmd(command uint8) (uint16, error) {
	result, err := C.i2c_smbus_read_word_data(C.int(i2c.file.Fd()), C.__u8(command))
	if result == -1 {
		return 0, err
	}
	return uint16(result), nil
}

// Perform SMBus Write Word Data transaction.
func (i2c *I2C) WriteUint16Cmd(command uint8, value uint16) error {
	result, err := C.i2c_smbus_write_word_data(C.int(i2c.file.Fd()), C.__u8(command), C.__u16(value))
	if result == -1 {
		return err
	}
	return nil
}

// Perform SMBus Read Word Data transaction.
func (i2c *I2C) ReadInt16Cmd(command uint8) (int16, error) {
	result, err := C.i2c_smbus_read_word_data(C.int(i2c.file.Fd()), C.__u8(command))
	if result == -1 {
		return 0, err
	}
	if result >= 1<<15 {
		result -= 1 << 16
	}
	return int16(result), nil
}

// Perform SMBus Write Word Data transaction.
func (i2c *I2C) WriteInt16Cmd(command uint8, value int16) error {
	return i2c.WriteUint16Cmd(command, uint16(value))
}

// Perform SMBus Quick transaction.
func (i2c *I2C) WriteQuick() error {
	result, err := C.i2c_smbus_write_quick(C.int(i2c.file.Fd()), C.I2C_SMBUS_WRITE)
	if result != 0 {
		return err
	}
	return nil
}

// Perform SMBus Process Call transaction.
//
// Note: although i2c_smbus_process_call returns a value, according to
// smbusmodule.c this method does not return a value by default.
//
// Set _compat = False on the SMBus instance to get a return value.
func (i2c *I2C) ProcessCall(command uint8, value uint16) (uint16, error) {
	result, err := C.i2c_smbus_process_call(C.int(i2c.file.Fd()), C.__u8(command), C.__u16(value))
	if result == -1 {
		return 0, err
	}
	return uint16(result), nil
}

// Perform SMBus Block Process Call transaction.
func (i2c *I2C) ProcessCallBlock(command uint8, block []byte) ([]byte, error) {
	length := len(block)
	if length == 0 || length > C.I2C_SMBUS_BLOCK_MAX {
		return nil, fmt.Errorf("Length of block is %d, but must be in the range 1 to %d", length, C.I2C_SMBUS_BLOCK_MAX)
	}
	data := make([]byte, length+1, C.I2C_SMBUS_BLOCK_MAX+2)
	data[0] = byte(length)
	copy(data[1:], block)
	result, err := C.i2c_smbus_access(C.int(i2c.file.Fd()), C.I2C_SMBUS_WRITE, C.__u8(command), C.I2C_SMBUS_BLOCK_PROC_CALL, (*C.union_i2c_smbus_data)(unsafe.Pointer(&data[0])))
	if result != 0 {
		return nil, err
	}
	return data[1 : 1+data[0]], nil
}

// Perform SMBus Read Block Data transaction.
func (i2c *I2C) ReadBlock(command uint8) ([]byte, error) {
	data := make([]byte, C.I2C_SMBUS_BLOCK_MAX+2)
	result, err := C.i2c_smbus_access(C.int(i2c.file.Fd()), C.I2C_SMBUS_READ, C.__u8(command), C.I2C_SMBUS_BLOCK_DATA, (*C.union_i2c_smbus_data)(unsafe.Pointer(&data[0])))
	if result != 0 {
		return nil, err
	}
	return data[1 : 1+data[0]], nil
}

// Perform SMBus Write Block Data transaction.
func (i2c *I2C) WriteBlock(command uint8, block []byte) error {
	length := len(block)
	if length == 0 || length > C.I2C_SMBUS_BLOCK_MAX {
		return fmt.Errorf("Length of block is %d, but must be in the range 1 to %d", length, C.I2C_SMBUS_BLOCK_MAX)
	}
	data := make([]byte, length+1)
	data[0] = byte(length)
	copy(data[1:], block)
	result, err := C.i2c_smbus_access(C.int(i2c.file.Fd()), C.I2C_SMBUS_WRITE, C.__u8(command), C.I2C_SMBUS_BLOCK_DATA, (*C.union_i2c_smbus_data)(unsafe.Pointer(&data[0])))
	if result != 0 {
		return err
	}
	return nil
}

// TODO: Perform I2C Block Read transaction.
// With if len == 32 then arg = C.I2C_SMBUS_I2C_BLOCK_BROKEN

func (i2c *I2C) Close() error {
	return i2c.file.Close()
}
<commit_msg>removed dependency from libi2c-dev<commit_after>package bbio

// #include <stddef.h>
// #include <sys/types.h>
// #include <linux/i2c-dev.h>
import "C"

import (
	"fmt"
	"os"
	"syscall"
	"unsafe"
)

// I2C is a port of https://github.com/bivab/smbus-cffi/
type I2C struct {
	file    *os.File
	address int
}

// Connects the object to the specified SMBus.
func NewI2C(bus, address int) (*I2C, error) {
	filename := fmt.Sprintf("/dev/i2c-%d", bus)
	file, err := os.OpenFile(filename, os.O_RDWR, 0)
	if err != nil {
		return nil, err
	}

	i2c := &I2C{file: file, address: -1}
	err = i2c.SetAddress(address)
	if err != nil {
		file.Close()
		return nil, err
	}

	return i2c, nil
}

func (i2c *I2C) Address() int {
	return i2c.address
}

func (i2c *I2C) SetAddress(address int) error {
	if address != i2c.address {
		result, _, err := syscall.Syscall(syscall.SYS_IOCTL, i2c.file.Fd(), C.I2C_SLAVE, uintptr(address))
		if result != 0 {
			return err
		}
		i2c.address = address
	}
	return nil
}

func (i2c *I2C) SmbusAccess(readWrite, command uint8, size int, data unsafe.Pointer) (uintptr, error) {
	args := C.struct_i2c_smbus_ioctl_data{
		read_write: C.char(readWrite),
		command:    C.__u8(command),
		size:       C.int(size),
		data:       (*C.union_i2c_smbus_data)(data),
	}
	result, _, err := syscall.Syscall(syscall.SYS_IOCTL, i2c.file.Fd(), C.I2C_SMBUS, uintptr(unsafe.Pointer(&args)))
	if int(result) == -1 {
		return 0, err
	}
	return result, nil
}

// Perform SMBus Quick transaction.
func (i2c *I2C) WriteQuick(value uint8) error {
	_, err := i2c.SmbusAccess(value, 0, C.I2C_SMBUS_QUICK, nil)
	return err
}

// Perform SMBus Read Byte transaction.
func (i2c *I2C) ReadUint8() (result uint8, err error) {
	_, err = i2c.SmbusAccess(C.I2C_SMBUS_READ, 0, C.I2C_SMBUS_BYTE, unsafe.Pointer(&result))
	if err != nil {
		return 0, err
	}
	return 0xFF & result, nil
}

// Perform SMBus Write Byte transaction.
func (i2c *I2C) WriteUint8(value uint8) error {
	_, err := i2c.SmbusAccess(C.I2C_SMBUS_WRITE, value, C.I2C_SMBUS_BYTE, nil)
	return err
}

// Perform SMBus Read Byte transaction.
func (i2c *I2C) ReadInt8() (int8, error) {
	result, err := i2c.ReadUint8()
	return int8(result), err
}

// Perform SMBus Write Byte transaction.
func (i2c *I2C) WriteInt8(value int8) error {
	return i2c.WriteUint8(uint8(value))
}

// Perform SMBus Read Byte Data transaction.
func (i2c *I2C) ReadUint8Cmd(command uint8) (result uint8, err error) {
	_, err = i2c.SmbusAccess(C.I2C_SMBUS_READ, command, C.I2C_SMBUS_BYTE_DATA, unsafe.Pointer(&result))
	if err != nil {
		return 0, err
	}
	return 0xFF & result, nil
}

// Perform SMBus Write Byte Data transaction.
func (i2c *I2C) WriteUint8Cmd(command uint8, value uint8) error {
	_, err := i2c.SmbusAccess(C.I2C_SMBUS_WRITE, command, C.I2C_SMBUS_BYTE_DATA, unsafe.Pointer(&value))
	return err
}

// Perform SMBus Read Byte Data transaction.
func (i2c *I2C) ReadInt8Cmd(command uint8) (int8, error) {
	result, err := i2c.ReadUint8Cmd(command)
	return int8(result), err
}

// Perform SMBus Write Byte Data transaction.
func (i2c *I2C) WriteInt8Cmd(command uint8, value int8) error {
	return i2c.WriteUint8Cmd(command, uint8(value))
}

// Perform SMBus Read Word Data transaction.
func (i2c *I2C) ReadUint16Cmd(command uint8) (result uint16, err error) {
	_, err = i2c.SmbusAccess(C.I2C_SMBUS_READ, command, C.I2C_SMBUS_WORD_DATA, unsafe.Pointer(&result))
	if err != nil {
		return 0, err
	}
	return 0xFFFF & result, nil
}

// Perform SMBus Write Word Data transaction.
func (i2c *I2C) WriteUint16Cmd(command uint8, value uint16) error {
	_, err := i2c.SmbusAccess(C.I2C_SMBUS_WRITE, command, C.I2C_SMBUS_WORD_DATA, unsafe.Pointer(&value))
	return err
}

// Perform SMBus Read Word Data transaction.
func (i2c *I2C) ReadInt16Cmd(command uint8) (int16, error) {
	result, err := i2c.ReadUint16Cmd(command)
	return int16(result), err
}

// Perform SMBus Write Word Data transaction.
func (i2c *I2C) WriteInt16Cmd(command uint8, value int16) error {
	return i2c.WriteUint16Cmd(command, uint16(value))
}

// Perform SMBus Process Call transaction.
//
// Note: although i2c_smbus_process_call returns a value, according to
// smbusmodule.c this method does not return a value by default.
//
// Set _compat = False on the SMBus instance to get a return value.
func (i2c *I2C) ProcessCall(command uint8, value uint16) (uint16, error) {
	_, err := i2c.SmbusAccess(C.I2C_SMBUS_WRITE, command, C.I2C_SMBUS_PROC_CALL, unsafe.Pointer(&value))
	if err != nil {
		return 0, err
	}
	return 0xFFFF & value, nil
}

// Perform SMBus Block Process Call transaction.
func (i2c *I2C) ProcessCallBlock(command uint8, block []byte) ([]byte, error) {
	length := len(block)
	if length == 0 || length > C.I2C_SMBUS_BLOCK_MAX {
		return nil, fmt.Errorf("Length of block is %d, but must be in the range 1 to %d", length, C.I2C_SMBUS_BLOCK_MAX)
	}
	data := make([]byte, length+1, C.I2C_SMBUS_BLOCK_MAX+2)
	data[0] = byte(length)
	copy(data[1:], block)
	_, err := i2c.SmbusAccess(C.I2C_SMBUS_WRITE, command, C.I2C_SMBUS_BLOCK_PROC_CALL, unsafe.Pointer(&data[0]))
	if err != nil {
		return nil, err
	}
	return data[1 : 1+data[0]], nil
}

// Perform SMBus Read Block Data transaction.
func (i2c *I2C) ReadBlock(command uint8) ([]byte, error) {
	data := make([]byte, C.I2C_SMBUS_BLOCK_MAX+2)
	_, err := i2c.SmbusAccess(C.I2C_SMBUS_READ, command, C.I2C_SMBUS_BLOCK_DATA, unsafe.Pointer(&data[0]))
	if err != nil {
		return nil, err
	}
	return data[1 : 1+data[0]], nil
}

// Perform SMBus Write Block Data transaction.
func (i2c *I2C) WriteBlock(command uint8, block []byte) error {
	length := len(block)
	if length == 0 || length > C.I2C_SMBUS_BLOCK_MAX {
		return fmt.Errorf("Length of block is %d, but must be in the range 1 to %d", length, C.I2C_SMBUS_BLOCK_MAX)
	}
	data := make([]byte, length+1)
	data[0] = byte(length)
	copy(data[1:], block)
	_, err := i2c.SmbusAccess(C.I2C_SMBUS_WRITE, command, C.I2C_SMBUS_BLOCK_DATA, unsafe.Pointer(&data[0]))
	return err
}

// TODO: Perform I2C Block Read transaction.
// With if len == 32 then arg = C.I2C_SMBUS_I2C_BLOCK_BROKEN instead of I2C_SMBUS_I2C_BLOCK_DATA ???

func (i2c *I2C) Close() error {
	return i2c.file.Close()
}
<|endoftext|>


<commit_before>package main

import(
	"fmt"
	"net/textproto"
	"time"
	"sync"
	"os"
	"bufio"
	"regexp"
	"runtime"
)

type command func(*textproto.Conn, string, string, string)

var funcMap map[string]command = make(map[string]command)

func errOut(err error){
	fmt.Println("ERROR: ", err.Error())
	var trace []byte
	runtime.Stack(trace, false)
	fmt.Print(trace)
}

func readToConsole(socket *textproto.Conn, wg sync.WaitGroup){
	pingRegex := regexp.MustCompile("^PING (.*)")
	line, line_err := socket.Reader.ReadLine()
	for ; line_err == nil; line, line_err = socket.Reader.ReadLine() {
		fmt.Println(line)
		if match := pingRegex.FindStringSubmatch(line); match != nil {
			socket.Writer.PrintfLine("PONG ", match[1])
			fmt.Println("PONG", match[1])
		}
	}
	if line_err != nil {
		errOut(line_err)
	}
	wg.Done()
}

func readFromConsole(socket *textproto.Conn, wg sync.WaitGroup){
	in := bufio.NewReader(os.Stdin)
	str, _, err := in.ReadLine()
	for ; err == nil; str, _, err = in.ReadLine() {
		write_err := socket.Writer.PrintfLine(string(str))
		if write_err != nil {
			errOut(write_err)
		}
	}
	if err != nil {
		errOut(err)
	}
	wg.Done()
}

func main(){
	socket, err := textproto.Dial("tcp", "irc.tamu.edu:6667")
	if err != nil {
		errOut(err)
		return
	}
	write_err := socket.Writer.PrintfLine("NICK yaircb")
	if write_err != nil {
		errOut(write_err)
	}
	time.Sleep(1 * time.Second)
	var wg sync.WaitGroup
	wg.Add(1)
	go readToConsole(socket, wg)
	write_err = socket.Writer.PrintfLine("USER yaircb * * gobot")
	if write_err != nil {
		errOut(write_err)
	}
	write_err = socket.Writer.PrintfLine("JOIN #ttestt")
	if write_err != nil {
		errOut(write_err)
	}
	wg.Add(1)
	go readFromConsole(socket, wg)
	source(socket, "#ttestt", "", "")
	f := funcMap["source"]
	f(socket, "#ttestt", "", "")
	wg.Wait()
}
<commit_msg>make one function to write to server, dont give all functions socket, only reader or writer<commit_after>package main

import(
	"fmt"
	"net/textproto"
	"time"
	"sync"
	"os"
	"bufio"
	"regexp"
	"runtime"
)

type command func(*textproto.Conn, string, string, string)

var funcMap map[string]command = make(map[string]command)

func errOut(err error){
	fmt.Println("ERROR: ", err.Error())
	var trace []byte
	runtime.Stack(trace, false)
	fmt.Print(trace)
}

func writeToServer(w textproto.Writer, srvChan chan string, wg sync.WaitGroup) {
	err := w.PrintfLine(<-srvChan)
	for ; err == nil; w.PrintfLine(<-srvChan) {}
	if err != nil {
		errOut(err)
	}
	wg.Done()
}

func writeToConsole(r textproto.Reader, srvChan chan string, wg sync.WaitGroup){
	pingRegex := regexp.MustCompile("^PING (.*)")
	line, line_err := r.ReadLine()
	for ; line_err == nil; line, line_err = r.ReadLine() {
		fmt.Println(line)
		if match := pingRegex.FindStringSubmatch(line); match != nil {
			srvChan <- ("PONG " + match[1])
			fmt.Println("PONG", match[1])
		}
	}
	if line_err != nil {
		errOut(line_err)
	}
	wg.Done()
}

func readFromConsole(srvChan chan string, wg sync.WaitGroup){
	in := bufio.NewReader(os.Stdin)
	str, _, err := in.ReadLine()
	for ; err == nil; str, _, err = in.ReadLine() {
		srvChan <- string(str)
	}
	if err != nil {
		errOut(err)
	}
	wg.Done()
}

func main(){
	srvChan := make(chan string)
	socket, err := textproto.Dial("tcp", "irc.tamu.edu:6667")
	if err != nil {
		errOut(err)
		return
	}
	r := socket.Reader
	w := socket.Writer
	write_err := w.PrintfLine("NICK yaircb")
	if write_err != nil {
		errOut(write_err)
	}
	time.Sleep(1 * time.Second)
	var wg sync.WaitGroup
	wg.Add(1)
	go writeToConsole(r, srvChan, wg)
	write_err = w.PrintfLine("USER yaircb * * gobot")
	if write_err != nil {
		errOut(write_err)
	}
	write_err = w.PrintfLine("JOIN #ttestt")
	if write_err != nil {
		errOut(write_err)
	}
	wg.Add(2)
	go writeToServer(w, srvChan, wg)
	go readFromConsole(srvChan, wg)
	source(socket, "#ttestt", "", "")
	f := funcMap["source"]
	f(socket, "#ttestt", "", "")
	wg.Wait()
}
<|endoftext|>


<commit_before>package qless

import (
	"github.com/garyburd/redigo/redis"
)

var (
	jobStates   = []string{"stalled", "running", "scheduled", "depends", "recurring"}
	finishBytes = []byte(`{"finish":"yes"}`)
)

type Job interface {
	JID() string
	Class() string
	State() string
	Queue() string
	Worker() string
	Tracked() bool
	Priority() int
	Expires() int64
	Retries() int
	Remaining() int
	Data() []byte
	Tags() []string
	History() []History
	Failure() interface{}
	Dependents() []string
	Dependencies() []string

	// operations
	Heartbeat() (bool, error)
	Fail(typ, message string) (bool, error)
	Complete() (string, error)
	CompleteWithNoData() (string, error)
	HeartbeatWithNoData() (bool, error)
	Cancel()
	Retry(delay int) (int, error)
}

//easyjson:json
type job struct {
	d *jobData
	c *Client
}

func (j *job) JID() string {
	return j.d.JID
}

func (j *job) Class() string {
	return j.d.Class
}

func (j *job) State() string {
	return j.d.State
}

func (j *job) Queue() string {
	return j.d.Queue
}

func (j *job) Worker() string {
	return j.d.Worker
}

func (j *job) Tracked() bool {
	return j.d.Tracked
}

func (j *job) Priority() int {
	return j.d.Priority
}

func (j *job) Expires() int64 {
	return j.d.Expires
}

func (j *job) Retries() int {
	return j.d.Retries
}

func (j *job) Remaining() int {
	return j.d.Remaining
}

func (j *job) Data() []byte {
	return j.d.Data
}

func (j *job) Tags() []string {
	return j.d.Tags
}

func (j *job) History() []History {
	return j.d.History
}

func (j *job) Failure() interface{} {
	return j.d.Failure
}

func (j *job) Dependents() []string {
	return j.d.Dependents
}

func (j *job) Dependencies() []string {
	return j.d.Dependencies
}

// Move this from it's current queue into another
func (j *job) Move(queueName string) (string, error) {
	return redis.String(j.c.Do("put", timestamp(), queueName, j.d.JID, j.d.Class, string(j.d.Data), 0))
}

// Fail this job
func (j *job) Fail(typ, message string) (bool, error) {
	return Bool(j.c.Do("fail", timestamp(), j.d.JID, j.d.Worker, typ, message, string(j.d.Data)))
}

// Heartbeats this job
func (j *job) Heartbeat() (bool, error) {
	return Bool(j.c.Do("heartbeat", timestamp(), j.d.JID, j.d.Worker, string(j.d.Data)))
}

// Completes this job
// returns state, error
func (j *job) Complete() (string, error) {
	return redis.String(j.c.Do("complete", timestamp(), j.d.JID, j.d.Worker, j.d.Queue, string(j.d.Data)))
}

//for big job, save memory in redis
func (j *job) CompleteWithNoData() (string, error) {
	return redis.String(j.c.Do("complete", timestamp(), j.d.JID, j.d.Worker, j.d.Queue, finishBytes))
}

func (j *job) HeartbeatWithNoData() (bool, error) {
	return Bool(j.c.Do("heartbeat", timestamp(), j.d.JID, j.d.Worker))
}

// Cancels this job
func (j *job) Cancel() {
	j.c.Do("cancel", timestamp(), j.d.JID)
}

// Track this job
func (j *job) Track() (bool, error) {
	return Bool(j.c.Do("track", timestamp(), "track", j.d.JID))
}

// Untrack this job
func (j *job) Untrack() (bool, error) {
	return Bool(j.c.Do("track", timestamp(), "untrack", j.d.JID))
}

func (j *job) AddTags(tags ...interface{}) (string, error) {
	args := []interface{}{"tag", timestamp(), "add", j.d.JID}
	args = append(args, tags...)
	return redis.String(j.c.Do(args...))
}

func (j *job) RemoveTags(tags ...interface{}) (string, error) {
	args := []interface{}{"tag", timestamp(), "remove", j.d.JID}
	args = append(args, tags...)
	return redis.String(j.c.Do(args...))
}

func (j *job) Retry(delay int) (int, error) {
	return redis.Int(j.c.Do("retry", timestamp(), j.d.JID, j.d.Queue, j.d.Worker, delay))
}

func (j *job) Depend(jids ...interface{}) (string, error) {
	args := []interface{}{"depends", timestamp(), j.d.JID, "on"}
	args = append(args, jids...)
	return redis.String(j.c.Do(args...))
}

func (j *job) Undepend(jids ...interface{}) (string, error) {
	args := []interface{}{"depends", timestamp(), j.d.JID, "off"}
	args = append(args, jids...)
	return redis.String(j.c.Do(args...))
}
<commit_msg>they are already bytes<commit_after>package qless

import (
	"github.com/garyburd/redigo/redis"
)

var (
	jobStates   = []string{"stalled", "running", "scheduled", "depends", "recurring"}
	finishBytes = []byte(`{"finish":"yes"}`)
)

type Job interface {
	JID() string
	Class() string
	State() string
	Queue() string
	Worker() string
	Tracked() bool
	Priority() int
	Expires() int64
	Retries() int
	Remaining() int
	Data() []byte
	Tags() []string
	History() []History
	Failure() interface{}
	Dependents() []string
	Dependencies() []string

	// operations
	Heartbeat() (bool, error)
	Fail(typ, message string) (bool, error)
	Complete() (string, error)
	CompleteWithNoData() (string, error)
	HeartbeatWithNoData() (bool, error)
	Cancel()
	Retry(delay int) (int, error)
}

//easyjson:json
type job struct {
	d *jobData
	c *Client
}

func (j *job) JID() string {
	return j.d.JID
}

func (j *job) Class() string {
	return j.d.Class
}

func (j *job) State() string {
	return j.d.State
}

func (j *job) Queue() string {
	return j.d.Queue
}

func (j *job) Worker() string {
	return j.d.Worker
}

func (j *job) Tracked() bool {
	return j.d.Tracked
}

func (j *job) Priority() int {
	return j.d.Priority
}

func (j *job) Expires() int64 {
	return j.d.Expires
}

func (j *job) Retries() int {
	return j.d.Retries
}

func (j *job) Remaining() int {
	return j.d.Remaining
}

func (j *job) Data() []byte {
	return j.d.Data
}

func (j *job) Tags() []string {
	return j.d.Tags
}

func (j *job) History() []History {
	return j.d.History
}

func (j *job) Failure() interface{} {
	return j.d.Failure
}

func (j *job) Dependents() []string {
	return j.d.Dependents
}

func (j *job) Dependencies() []string {
	return j.d.Dependencies
}

// Move this from it's current queue into another
func (j *job) Move(queueName string) (string, error) {
	return redis.String(j.c.Do("put", timestamp(), queueName, j.d.JID, j.d.Class, []byte(j.d.Data), 0))
}

// Fail this job
func (j *job) Fail(typ, message string) (bool, error) {
	return Bool(j.c.Do("fail", timestamp(), j.d.JID, j.d.Worker, typ, message, []byte(j.d.Data)))
}

// Heartbeats this job
func (j *job) Heartbeat() (bool, error) {
	return Bool(j.c.Do("heartbeat", timestamp(), j.d.JID, j.d.Worker, []byte(j.d.Data)))
}

// Completes this job
// returns state, error
func (j *job) Complete() (string, error) {
	return redis.String(j.c.Do("complete", timestamp(), j.d.JID, j.d.Worker, j.d.Queue, []byte(j.d.Data)))
}

//for big job, save memory in redis
func (j *job) CompleteWithNoData() (string, error) {
	return redis.String(j.c.Do("complete", timestamp(), j.d.JID, j.d.Worker, j.d.Queue, finishBytes))
}

func (j *job) HeartbeatWithNoData() (bool, error) {
	return Bool(j.c.Do("heartbeat", timestamp(), j.d.JID, j.d.Worker))
}

// Cancels this job
func (j *job) Cancel() {
	j.c.Do("cancel", timestamp(), j.d.JID)
}

// Track this job
func (j *job) Track() (bool, error) {
	return Bool(j.c.Do("track", timestamp(), "track", j.d.JID))
}

// Untrack this job
func (j *job) Untrack() (bool, error) {
	return Bool(j.c.Do("track", timestamp(), "untrack", j.d.JID))
}

func (j *job) AddTags(tags ...interface{}) (string, error) {
	args := []interface{}{"tag", timestamp(), "add", j.d.JID}
	args = append(args, tags...)
	return redis.String(j.c.Do(args...))
}

func (j *job) RemoveTags(tags ...interface{}) (string, error) {
	args := []interface{}{"tag", timestamp(), "remove", j.d.JID}
	args = append(args, tags...)
	return redis.String(j.c.Do(args...))
}

func (j *job) Retry(delay int) (int, error) {
	return redis.Int(j.c.Do("retry", timestamp(), j.d.JID, j.d.Queue, j.d.Worker, delay))
}

func (j *job) Depend(jids ...interface{}) (string, error) {
	args := []interface{}{"depends", timestamp(), j.d.JID, "on"}
	args = append(args, jids...)
	return redis.String(j.c.Do(args...))
}

func (j *job) Undepend(jids ...interface{}) (string, error) {
	args := []interface{}{"depends", timestamp(), j.d.JID, "off"}
	args = append(args, jids...)
	return redis.String(j.c.Do(args...))
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/kidoman/embd"
	_ "github.com/kidoman/embd/host/all"
	"os"
	"strings"
	"time"
	"github.com/stianeikeland/go-rpio"
)

var (
	ledRed = rpio.Pin(4)
	ledYellow = rpio.Pin(17)
	ledGreen = rpio.Pin(27)
)

// var (
// 	ledRed, _    = embd.NewDigitalPin(7)
// 	ledYellow, _ = embd.NewDigitalPin(0)
// 	ledGreen, _  = embd.NewDigitalPin(2)
// )

func getLEDString(color string) string {
	return "Toggle " + strings.ToUpper(color)
}

func getToggledValue(pin embd.DigitalPin) int {
	val,_ := pin.Read()
	if val == embd.High {
		return embd.Low
	} else {
		return embd.High
	}
}

func toggleLED(pin embd.DigitalPin, color string) {
	fmt.Println(getLEDString(color))
	toggledValue := getToggledValue(pin)
	fmt.Println("Val to write", toggledValue)
	embd.DigitalWrite(pin.N(), embd.High)
	// err := pin.Write(toggledValue)
	// if err != nil {
 // 		fmt.Println(err)
 // 		os.Exit(1)
	// }
}

func toggleLED(pin rpio.Pin, color string)  {
	fmt.Println(getLEDString(color))
	pin.Toggle()
}

func initLEDs() {
	// embd.SetDirection(4, embd.Out)
	// embd.SetDirection(17, embd.Out)
	// embd.SetDirection(27, embd.Out)
	ledRed.Output()
	ledYellow.Output()
	ledGreen.Output()
}

func main() {
	fmt.Println("Parsing parameters")
	num := flag.Int("num", 0, "number of blinks")
	flag.Parse()

	fmt.Println("Number of blinks:", *num)

	fmt.Println("Opening rpio access")

	var err = rpio.Open()
	// embd.InitGPIO()

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	defer rpio.Close()
	// defer embd.CloseGPIO()

	fmt.Println("Pin as output")

	for i := 0; i < *num; i++ {
		if i%3 == 0 {
			toggleLED(ledRed, "red")
		} else if i%3 == 1 {
			toggleLED(ledYellow, "yellow")
		} else {
			toggleLED(ledGreen, "green")
		}
		time.Sleep(time.Second)
	}
}
<commit_msg>Remove duplicates<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/kidoman/embd"
	_ "github.com/kidoman/embd/host/all"
	"os"
	"strings"
	"time"
	"github.com/stianeikeland/go-rpio"
)

var (
	ledRed = rpio.Pin(4)
	ledYellow = rpio.Pin(17)
	ledGreen = rpio.Pin(27)
)

// var (
// 	ledRed, _    = embd.NewDigitalPin(7)
// 	ledYellow, _ = embd.NewDigitalPin(0)
// 	ledGreen, _  = embd.NewDigitalPin(2)
// )

func getLEDString(color string) string {
	return "Toggle " + strings.ToUpper(color)
}

func getToggledValue(pin embd.DigitalPin) int {
	val,_ := pin.Read()
	if val == embd.High {
		return embd.Low
	} else {
		return embd.High
	}
}

// func toggleLED(pin embd.DigitalPin, color string) {
// 	fmt.Println(getLEDString(color))
// 	toggledValue := getToggledValue(pin)
// 	fmt.Println("Val to write", toggledValue)
// 	embd.DigitalWrite(pin.N(), embd.High)
// }

func toggleLED(pin rpio.Pin, color string)  {
	fmt.Println(getLEDString(color))
	pin.Toggle()
}

func initLEDs() {
	// ledRed.SetDirection(embd.Out)
	// ledYellow.SetDirection(embd.Out)
	// ledGreen.SetDirection(embd.Out)
	ledRed.Output()
	ledYellow.Output()
	ledGreen.Output()
}

func main() {
	fmt.Println("Parsing parameters")
	num := flag.Int("num", 0, "number of blinks")
	flag.Parse()

	fmt.Println("Number of blinks:", *num)

	fmt.Println("Opening rpio access")

	var err = rpio.Open()
	// embd.InitGPIO()

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	defer rpio.Close()
	// defer embd.CloseGPIO()

	fmt.Println("Pin as output")

	for i := 0; i < *num; i++ {
		if i%3 == 0 {
			toggleLED(ledRed, "red")
		} else if i%3 == 1 {
			toggleLED(ledYellow, "yellow")
		} else {
			toggleLED(ledGreen, "green")
		}
		time.Sleep(time.Second)
	}
}
<|endoftext|>


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

package corridor

import (
	"errors"
	"math"

	"github.com/gonum/matrix/mat64"
)

// compute euclidean distance for a pair of subscript indices
func Distance(aSubs, bSubs []int) (dist float64) {

	// initialize variables
	var x0 float64 = float64(aSubs[0])
	var x1 float64 = float64(bSubs[0])
	var y0 float64 = float64(aSubs[1])
	var y1 float64 = float64(bSubs[1])
	var pow float64 = 2.0
	var dx float64 = x1 - x0
	var dy float64 = y1 - y0

	// compute distance
	var output float64 = math.Sqrt(math.Pow(dx, pow) + math.Pow(dy, pow))

	// return final output
	return output
}

// alldistance computes the distance from each location with the input
// search domain and a given point defined by an input pair of row
// column subscripts
func AllDistance(aSubs []int, searchDomain *mat64.Dense) (allDistMatrix *mat64.Dense) {

	// get matrix dimensions
	rows, cols := searchDomain.Dims()

	// initialize new output matrix
	output := mat64.NewDense(rows, cols, nil)

	// initialize destination point subscript slice
	bSubs := make([]int, 2)

	// loop through all values and compute minimum distances
	for i := 0; i < rows; i++ {
		for j := 0; j < cols; j++ {
			bSubs[0] = i
			bSubs[1] = j
			output.Set(bSubs[0], bSubs[1], Distance(aSubs, bSubs))
		}
	}

	// return output
	return output

}

// compute the minimum distance between a given input point and
// the subscripts comprised of a line segement joining two other
// input points
func MinDistance(pSubs, aSubs, bSubs []int) (minDist float64) {

	// initialize variables
	var x float64 = float64(pSubs[0])
	var y float64 = float64(pSubs[1])
	var x0 float64 = float64(aSubs[0])
	var y0 float64 = float64(aSubs[1])
	var x1 float64 = float64(bSubs[0])
	var y1 float64 = float64(bSubs[1])

	// compute difference components
	a := x - x0
	b := y - y0
	c := x1 - x0
	d := y1 - y0

	// compute dot product of difference components
	dot := a*c + b*d
	lenSq := c*c + d*d

	// initialize parameter
	var param float64 = -1.0

	// if zero length condition
	if lenSq != 0 {
		param = dot / lenSq
	}

	// initialize transform variables
	var xx, yy float64

	// switch transform mechanism on orientation
	if param < 0 {
		xx = x0
		yy = y0
	} else if param > 1 {
		xx = x1
		yy = y1
	} else {
		xx = x0 + param*c
		yy = y0 + param*d
	}

	// execute transform
	var dx float64 = x - xx
	var dy float64 = y - yy

	// generate output
	output := math.Sqrt(dx*dx + dy*dy)

	// return final output
	return output
}

// allmindistance computes the distance from each location within the
// input search domain and to the nearest subscript located along the
// line formed by the two input subscripts
func AllMinDistance(aSubs, bSubs []int, searchDomain *mat64.Dense) (allMinDistMatrix *mat64.Dense) {

	// get matrix dimensions
	rows, cols := searchDomain.Dims()

	// initialize new output matrix
	output := mat64.NewDense(rows, cols, nil)

	// initialize slice
	pSubs := make([]int, 2)

	// loop through all values and compute minimum distances
	for i := 0; i < rows; i++ {
		for j := 0; j < cols; j++ {
			pSubs[0] = i
			pSubs[1] = j
			curMinDist := MinDistance(pSubs, aSubs, bSubs)
			output.Set(pSubs[0], pSubs[1], curMinDist)
		}
	}

	// return final output
	return output
}

// distance to bands recodes a distance matrix computed from a single
// source location to ordinal set of bands of increasing distance
func AllDistanceToBands(distanceMatrix *mat64.Dense, bandCount int) (bandMatrix *mat64.Dense) {

	// get matrix dimensions
	rows, cols := distanceMatrix.Dims()

	// initialize output
	output := mat64.NewDense(rows, cols, nil)

	// check band count against input distance matrix size
	if bandCount > rows || bandCount > cols {
		err := errors.New("Input band count too large for input distance matrix \n")
		panic(err)
	}

	// generate band range
	minDist := distanceMatrix.Min()
	maxDist := distanceMatrix.Max()

	// initialize band interval unit and slice
	bandUnit := (maxDist - minDist) / float64(bandCount+1)
	bandInt := make([]float64, bandCount+1)

	// generate band intervals
	for i := 0; i < bandCount+1; i++ {
		if i == 0 {
			bandInt[i] = 0
		} else {
			bandInt[i] = bandInt[i-1] + bandUnit
		}
	}

	// perform conversion to bands
	for i := 0; i < len(bandInt)-1; i++ {
		for j := 0; j < rows; j++ {
			for k := 0; k < rows; k++ {
				if distanceMatrix.At(j, k) > bandInt[i] && distanceMatrix.At(j, k) < bandInt[i+1] {
					output.Set(j, k, float64(i))
				} else if distanceMatrix.At(j, k) > bandInt[i+1] {
					output.Set(j, k, float64(i+1))
				}
			}
		}
	}

	// return output
	return output
}

// bresenham generates the list of subscript indices corresponding to the
// euclidean shortest paths connecting two subscript pairs in discrete space
func Bresenham(aSubs, bSubs []int) (lineSubs [][]int) {

	// initialize variables
	var x0 int = aSubs[0]
	var x1 int = bSubs[0]
	var y0 int = aSubs[1]
	var y1 int = bSubs[1]

	// check row differential
	dx := x1 - x0
	if dx < 0 {
		dx = -dx
	}

	// check column differential
	dy := y1 - y0

	// if differential is negative flip
	if dy < 0 {
		dy = -dy
	}

	// initialize stride variables
	var sx, sy int

	// set row stride direction
	if x0 < x1 {
		sx = 1
	} else {
		sx = -1
	}

	// set column stride direction
	if y0 < y1 {
		sy = 1
	} else {
		sy = -1
	}

	// calculate error component
	err := dx - dy

	// initialize output 2D slice vector
	dist := math.Ceil(Distance(aSubs, bSubs))
	maxLen := int(dist)
	output := make([][]int, 0, maxLen)

	// loop through and generate subscripts
	for {
		var val = []int{x0, y0}
		output = append(output, val)
		if x0 == x1 && y0 == y1 {
			break
		}
		e2 := 2 * err
		if e2 > -dy {
			err -= dy
			x0 += sx
		}
		if e2 < dx {
			err += dx
			y0 += sy
		}
	}

	// return final output
	return output
}

// function to return the subscript indices of the cells corresponding to the
// queens neighborhood for a given subscript pair
func NeighborhoodSubs(row, col int) (subs [9][2]int) {

	// initialize output slice
	var output [9][2]int

	// write neighborhood subscript values
	output[0][0] = row - 1
	output[0][1] = col - 1
	output[1][0] = row - 1
	output[1][1] = col
	output[2][0] = row - 1
	output[2][1] = col + 1
	output[3][0] = row
	output[3][1] = col - 1
	output[4][0] = row
	output[4][1] = col
	output[5][0] = row
	output[5][1] = col + 1
	output[6][0] = row + 1
	output[6][1] = col - 1
	output[7][0] = row + 1
	output[7][1] = col
	output[8][0] = row + 1
	output[8][1] = col + 1

	return output
}

// function to validate an input sub domain for use in generating
// a chromosomal mutation via the random walk procedure
func ValidateSubDomain(subSource, subDestin []int, subMat *mat64.Dense) bool {

	// initialize output
	var output bool

	// generate sub source neighborhood
	sNeigh := NeighborhoodSubs(subSource[0], subSource[1])

	// generate sub destination neighborhood
	dNeigh := NeighborhoodSubs(subDestin[0], subDestin[1])

	// generate center row
	centerRow := subMat.RowView(2)

	// generate center column
	centerCol := subMat.ColView(2)

	// initialize summation variables
	var sSum float64 = 0.0
	var dSum float64 = 0.0
	var rSum float64 = 0.0
	var cSum float64 = 0.0

	// enter for loop for start and destination sums
	for i := 0; i < 9; i++ {
		sSum = sSum + subMat.At(sNeigh[i][0], sNeigh[i][1])
		dSum = dSum + subMat.At(dNeigh[i][0], dNeigh[i][1])
	}

	// enter for loop for row column sums
	for j := 0; j < 5; j++ {
		rSum = rSum + centerRow.At(j, 0)
		cSum = cSum + centerCol.At(j, 0)
	}

	// check conditions to validate neighborhood
	if sSum <= 1.0 || dSum <= 1.0 || rSum == 0.0 || cSum == 0.0 {
		output = false
	} else {
		output = true
	}

	//return final output
	return output
}

// function validate the tabu neighborhood of an input pair of
// row column subscripts
func ValidateTabu(currentSubs []int, tabuMatrix *mat64.Dense) bool {

	// initialize output
	var output bool

	// initialize tabu neighborhood sum
	var tSum int = 0

	// generate neighborhood subscripts
	tNeigh := NeighborhoodSubs(currentSubs[0], currentSubs[1])

	// loop through and compute sum
	for i := 0; i < 9; i++ {
		if i != 4 {
			tSum += int(tabuMatrix.At(tNeigh[i][0], tNeigh[i][1]))
		}
	}

	// write output boolean
	if tSum == 0 {
		output = false
	} else {
		output = true
	}

	// return output
	return output
}

// function to count the number of digits in an input integer as
// its base ten logarithm
func DigitCount(input int) (digits int) {

	// compute digits as the log of the input
	output := int(math.Floor(math.Log10(float64(input))))

	// return output
	return output
}
<commit_msg>Added routine for computing binary orientation masks for arbitrary combinations of points situated within a given input search domain.<commit_after>// Copyright ©2015 The corridor Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.package main

package corridor

import (
	"errors"
	"math"

	"github.com/gonum/matrix/mat64"
)

// compute euclidean distance for a pair of subscript indices
func Distance(aSubs, bSubs []int) (dist float64) {

	// initialize variables
	var x0 float64 = float64(aSubs[0])
	var x1 float64 = float64(bSubs[0])
	var y0 float64 = float64(aSubs[1])
	var y1 float64 = float64(bSubs[1])
	var pow float64 = 2.0
	var dx float64 = x1 - x0
	var dy float64 = y1 - y0

	// compute distance
	var output float64 = math.Sqrt(math.Pow(dx, pow) + math.Pow(dy, pow))

	// return final output
	return output
}

// alldistance computes the distance from each location with the input
// search domain and a given point defined by an input pair of row
// column subscripts
func AllDistance(aSubs []int, searchDomain *mat64.Dense) (allDistMatrix *mat64.Dense) {

	// get matrix dimensions
	rows, cols := searchDomain.Dims()

	// initialize new output matrix
	output := mat64.NewDense(rows, cols, nil)

	// initialize destination point subscript slice
	bSubs := make([]int, 2)

	// loop through all values and compute minimum distances
	for i := 0; i < rows; i++ {
		for j := 0; j < cols; j++ {
			bSubs[0] = i
			bSubs[1] = j
			output.Set(bSubs[0], bSubs[1], Distance(aSubs, bSubs))
		}
	}

	// return output
	return output

}

// compute the minimum distance between a given input point and
// the subscripts comprised of a line segement joining two other
// input points
func MinDistance(pSubs, aSubs, bSubs []int) (minDist float64) {

	// initialize variables
	var x float64 = float64(pSubs[0])
	var y float64 = float64(pSubs[1])
	var x0 float64 = float64(aSubs[0])
	var y0 float64 = float64(aSubs[1])
	var x1 float64 = float64(bSubs[0])
	var y1 float64 = float64(bSubs[1])

	// compute difference components
	a := x - x0
	b := y - y0
	c := x1 - x0
	d := y1 - y0

	// compute dot product of difference components
	dot := a*c + b*d
	lenSq := c*c + d*d

	// initialize parameter
	var param float64 = -1.0

	// if zero length condition
	if lenSq != 0 {
		param = dot / lenSq
	}

	// initialize transform variables
	var xx, yy float64

	// switch transform mechanism on orientation
	if param < 0 {
		xx = x0
		yy = y0
	} else if param > 1 {
		xx = x1
		yy = y1
	} else {
		xx = x0 + param*c
		yy = y0 + param*d
	}

	// execute transform
	var dx float64 = x - xx
	var dy float64 = y - yy

	// generate output
	output := math.Sqrt(dx*dx + dy*dy)

	// return final output
	return output
}

// allmindistance computes the distance from each location within the
// input search domain and to the nearest subscript located along the
// line formed by the two input subscripts
func AllMinDistance(aSubs, bSubs []int, searchDomainMatrix *mat64.Dense) (allMinDistMatrix *mat64.Dense) {

	// get matrix dimensions
	rows, cols := searchDomainMatrix.Dims()

	// initialize new output matrix
	output := mat64.NewDense(rows, cols, nil)

	// initialize slice
	pSubs := make([]int, 2)

	// loop through all values and compute minimum distances
	for i := 0; i < rows; i++ {
		for j := 0; j < cols; j++ {
			pSubs[0] = i
			pSubs[1] = j
			curMinDist := MinDistance(pSubs, aSubs, bSubs)
			output.Set(pSubs[0], pSubs[1], curMinDist)
		}
	}

	// return final output
	return output
}

// distancebands recodes a distance matrix computed from a single
// source location to ordinal set of bands of increasing distance
func DistanceBands(distanceMatrix *mat64.Dense, bandCount int) (bandMatrix *mat64.Dense) {

	// get matrix dimensions
	rows, cols := distanceMatrix.Dims()

	// initialize output
	output := mat64.NewDense(rows, cols, nil)

	// check band count against input distance matrix size
	if bandCount > rows || bandCount > cols {
		err := errors.New("Input band count too large for input distance matrix \n")
		panic(err)
	}

	// generate band range
	minDist := distanceMatrix.Min()
	maxDist := distanceMatrix.Max()

	// initialize band interval unit and slice
	bandUnit := (maxDist - minDist) / float64(bandCount+1)
	bandInt := make([]float64, bandCount+1)

	// generate band intervals
	for i := 0; i < bandCount+1; i++ {
		if i == 0 {
			bandInt[i] = 0
		} else {
			bandInt[i] = bandInt[i-1] + bandUnit
		}
	}

	// perform conversion to the appropriate band interval
	for i := 0; i < len(bandInt)-1; i++ {
		for j := 0; j < rows; j++ {
			for k := 0; k < rows; k++ {
				if distanceMatrix.At(j, k) > bandInt[i] && distanceMatrix.At(j, k) < bandInt[i+1] {
					output.Set(j, k, float64(i))
				} else if distanceMatrix.At(j, k) > bandInt[i+1] {
					output.Set(j, k, float64(i+1))
				}
			}
		}
	}

	// return output
	return output
}

// orientation accepts as inputs a pair of point subscripts
// and returns a binary vector indicating the relative orientation
// of the first point to the second in binary terms
func Orientation(aSubs, bSubs []int) (orientationVector []int) {

	// initialize output
	output := make([]int, 2)

	// generate reference orientation row parameter
	if aSubs[0]-bSubs[0] < 0 {
		output[0] = 1
	} else if aSubs[0]-bSubs[0] == 0 {
		output[0] = 0
	} else if aSubs[0]-bSubs[0] > 0 {
		output[0] = -1
	}

	// generate reference orientation column parameter
	if aSubs[1]-bSubs[1] < 0 {
		output[1] = 1
	} else if aSubs[1]-bSubs[1] == 0 {
		output[1] = 0
	} else if aSubs[1]-bSubs[1] > 0 {
		output[1] = -1
	}

	// return output
	return output
}

// orientation mask returns a binary encoded matrix for
// a given point where all points orientated towards
// a given second point are encoded as 1 and all points
// orientated away from the given second point as 0
func OrientationMask(aSubs, bSubs []int, searchDomainMatrix *mat64.Dense) (orientationMask *mat64.Dense) {

	// generate matrix dimensions
	rows, cols := searchDomainMatrix.Dims()

	// initialize output matrix
	output := mat64.NewDense(rows, cols, nil)

	// generate reference orientation vectors
	sRefOrientVec := Orientation(aSubs, bSubs)
	dRefOrientVec := Orientation(bSubs, aSubs)

	// initialize current subs and orientation vectors
	curSubs := make([]int, 2)
	sOrientVec := make([]int, 2)
	dOrientVec := make([]int, 2)

	// loop through domain matrix and generate orientation matrix values
	for i := 0; i < rows; i++ {
		for j := 0; j < cols; j++ {

			// compute current orientation
			curSubs[0] = i
			curSubs[1] = j
			sOrientVec = Orientation(curSubs, bSubs)
			dOrientVec = Orientation(curSubs, aSubs)

			// check for match and assign values
			if sOrientVec[0] == sRefOrientVec[0] && sOrientVec[1] == sRefOrientVec[1] {
				if dOrientVec[0] == dRefOrientVec[0] && dOrientVec[1] == dRefOrientVec[1] {
					output.Set(i, j, 1.0)
				}
			}
		}
	}

	// return output
	return output
}

// bresenham generates the list of subscript indices corresponding to the
// euclidean shortest paths connecting two subscript pairs in discrete space
func Bresenham(aSubs, bSubs []int) (lineSubs [][]int) {

	// initialize variables
	var x0 int = aSubs[0]
	var x1 int = bSubs[0]
	var y0 int = aSubs[1]
	var y1 int = bSubs[1]

	// check row differential
	dx := x1 - x0
	if dx < 0 {
		dx = -dx
	}

	// check column differential
	dy := y1 - y0

	// if differential is negative flip
	if dy < 0 {
		dy = -dy
	}

	// initialize stride variables
	var sx, sy int

	// set row stride direction
	if x0 < x1 {
		sx = 1
	} else {
		sx = -1
	}

	// set column stride direction
	if y0 < y1 {
		sy = 1
	} else {
		sy = -1
	}

	// calculate error component
	err := dx - dy

	// initialize output 2D slice vector
	dist := math.Ceil(Distance(aSubs, bSubs))
	maxLen := int(dist)
	output := make([][]int, 0, maxLen)

	// loop through and generate subscripts
	for {
		var val = []int{x0, y0}
		output = append(output, val)
		if x0 == x1 && y0 == y1 {
			break
		}
		e2 := 2 * err
		if e2 > -dy {
			err -= dy
			x0 += sx
		}
		if e2 < dx {
			err += dx
			y0 += sy
		}
	}

	// return final output
	return output
}

// function to return the subscript indices of the cells corresponding to the
// queens neighborhood for a given subscript pair
func NeighborhoodSubs(row, col int) (subs [9][2]int) {

	// initialize output slice
	var output [9][2]int

	// write neighborhood subscript values
	output[0][0] = row - 1
	output[0][1] = col - 1
	output[1][0] = row - 1
	output[1][1] = col
	output[2][0] = row - 1
	output[2][1] = col + 1
	output[3][0] = row
	output[3][1] = col - 1
	output[4][0] = row
	output[4][1] = col
	output[5][0] = row
	output[5][1] = col + 1
	output[6][0] = row + 1
	output[6][1] = col - 1
	output[7][0] = row + 1
	output[7][1] = col
	output[8][0] = row + 1
	output[8][1] = col + 1

	return output
}

// function to validate an input sub domain for use in generating
// a chromosomal mutation via the random walk procedure
func ValidateSubDomain(subSource, subDestin []int, subMat *mat64.Dense) bool {

	// initialize output
	var output bool

	// generate sub source neighborhood
	sNeigh := NeighborhoodSubs(subSource[0], subSource[1])

	// generate sub destination neighborhood
	dNeigh := NeighborhoodSubs(subDestin[0], subDestin[1])

	// generate center row
	centerRow := subMat.RowView(2)

	// generate center column
	centerCol := subMat.ColView(2)

	// initialize summation variables
	var sSum float64 = 0.0
	var dSum float64 = 0.0
	var rSum float64 = 0.0
	var cSum float64 = 0.0

	// enter for loop for start and destination sums
	for i := 0; i < 9; i++ {
		sSum = sSum + subMat.At(sNeigh[i][0], sNeigh[i][1])
		dSum = dSum + subMat.At(dNeigh[i][0], dNeigh[i][1])
	}

	// enter for loop for row column sums
	for j := 0; j < 5; j++ {
		rSum = rSum + centerRow.At(j, 0)
		cSum = cSum + centerCol.At(j, 0)
	}

	// check conditions to validate neighborhood
	if sSum <= 1.0 || dSum <= 1.0 || rSum == 0.0 || cSum == 0.0 {
		output = false
	} else {
		output = true
	}

	//return final output
	return output
}

// function validate the tabu neighborhood of an input pair of
// row column subscripts
func ValidateTabu(currentSubs []int, tabuMatrix *mat64.Dense) bool {

	// initialize output
	var output bool

	// initialize tabu neighborhood sum
	var tSum int = 0

	// generate neighborhood subscripts
	tNeigh := NeighborhoodSubs(currentSubs[0], currentSubs[1])

	// loop through and compute sum
	for i := 0; i < 9; i++ {
		if i != 4 {
			tSum += int(tabuMatrix.At(tNeigh[i][0], tNeigh[i][1]))
		}
	}

	// write output boolean
	if tSum == 0 {
		output = false
	} else {
		output = true
	}

	// return output
	return output
}

// function to count the number of digits in an input integer as
// its base ten logarithm
func DigitCount(input int) (digits int) {

	// compute digits as the log of the input
	output := int(math.Floor(math.Log10(float64(input))))

	// return output
	return output
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"path"
)

// Simple logger for writing to a file. This is heavily
// based on https://github.com/siddontang/go-log.

// SimpleLogger is a basic logging struct that provide log rotating.
type SimpleLogger struct {
	file      *os.File
	filename  string
	maxBytes  int
	fileCount int
}

// NewSimpleLogger takes the filename, maxBytes and fileCount to create a
// SimpleLogger. maxBytes and fileCount are used to determine when to rotate
// the files.
func NewSimpleLogger(filename string, maxBytes, fileCount int) (*SimpleLogger, error) {
	dir := path.Dir(filename)
	os.Mkdir(dir, 0777)

	sl := &SimpleLogger{filename: filename, maxBytes: maxBytes, fileCount: fileCount}

	var err error
	sl.file, err = os.OpenFile(sl.filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		return nil, err
	}

	return sl, nil
}

// Write the given bytes to the file.
func (l *SimpleLogger) Write(b []byte) (int, error) {
	l.rotate()
	return l.file.Write(append(b, []byte("\n")...))
}

// Close the SimpleLogger's file handle.
func (l *SimpleLogger) Close() error {
	if l.file != nil {
		return l.file.Close()
	}
	return nil
}

func (l *SimpleLogger) rotate() error {
	f, err := l.file.Stat()
	if err != nil {
		return err
	}

	if l.maxBytes <= 0 {
		return fmt.Errorf("Max Bytes needs to be greater than 0 instead of: %d", l.maxBytes)
	}
	if f.Size() < int64(l.maxBytes) {
		return nil
	}

	if l.fileCount > 0 {
		l.file.Close()

		for i := l.fileCount - 1; i > 0; i-- {
			prev := fmt.Sprintf("%s.%d", l.filename, i)
			next := fmt.Sprintf("%s.%d", l.filename, i+1)

			os.Rename(prev, next)
		}

		next := fmt.Sprintf("%s.1", l.filename)
		os.Rename(l.filename, next)

		l.file, _ = os.OpenFile(l.filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	}

	return nil
}
<commit_msg>Prepend time to simple logger<commit_after>package main

import (
	"bytes"
	"fmt"
	"os"
	"path"
	"time"
)

// Simple logger for writing to a file. This is heavily
// based on https://github.com/siddontang/go-log.

// SimpleLogger is a basic logging struct that provide log rotating.
type SimpleLogger struct {
	file      *os.File
	filename  string
	maxBytes  int
	fileCount int
}

// NewSimpleLogger takes the filename, maxBytes and fileCount to create a
// SimpleLogger. maxBytes and fileCount are used to determine when to rotate
// the files.
func NewSimpleLogger(filename string, maxBytes, fileCount int) (*SimpleLogger, error) {
	dir := path.Dir(filename)
	os.Mkdir(dir, 0777)

	sl := &SimpleLogger{filename: filename, maxBytes: maxBytes, fileCount: fileCount}

	var err error
	sl.file, err = os.OpenFile(sl.filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		return nil, err
	}

	return sl, nil
}

// Write the given bytes to the file.
func (l *SimpleLogger) Write(b []byte) (int, error) {
	l.rotate()
	var buf bytes.Buffer
	buf.WriteString(fmt.Sprintf("%s: ", time.Now().Format("Mon Jan 2 15:04:05 -0700 MST 2006")))
	buf.Write(b)
	buf.WriteString("\n")
	return l.file.Write(buf.Bytes())
}

// Close the SimpleLogger's file handle.
func (l *SimpleLogger) Close() error {
	if l.file != nil {
		return l.file.Close()
	}
	return nil
}

func (l *SimpleLogger) rotate() error {
	f, err := l.file.Stat()
	if err != nil {
		return err
	}

	if l.maxBytes <= 0 {
		return fmt.Errorf("Max Bytes needs to be greater than 0 instead of: %d", l.maxBytes)
	}
	if f.Size() < int64(l.maxBytes) {
		return nil
	}

	if l.fileCount > 0 {
		l.file.Close()

		for i := l.fileCount - 1; i > 0; i-- {
			prev := fmt.Sprintf("%s.%d", l.filename, i)
			next := fmt.Sprintf("%s.%d", l.filename, i+1)

			os.Rename(prev, next)
		}

		next := fmt.Sprintf("%s.1", l.filename)
		os.Rename(l.filename, next)

		l.file, _ = os.OpenFile(l.filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	}

	return nil
}
<|endoftext|>


<commit_before>package log

import (
	"fmt"
	"log"
	"os"
)

type Logger struct {
	info      *log.Logger
	warning   *log.Logger
	error     *log.Logger
	slack     *log.Logger
	request   *log.Logger
	callDepth int
}

func New(prefix string, depth int) *Logger {

	l := &Logger{
		info:      log.New(os.Stdout, "", log.Ldate|log.Ltime|log.Lshortfile),
		warning:   log.New(os.Stdout, "", log.Ldate|log.Ltime|log.Lshortfile),
		error:     log.New(os.Stderr, "", log.Ldate|log.Ltime|log.Lshortfile),
		slack:     log.New(os.Stdout, "", log.Ldate|log.Ltime|log.Lshortfile),
		request:   log.New(os.Stdout, "", log.Ldate|log.Ltime),
		callDepth: depth,
	}

	l.SetPrefix(prefix)
	return l
}

var defaultLogger = New("", 3)

type BLogger interface {
	Errorf(format string, v ...interface{})
	Errorln(v ...interface{})
	Warningf(format string, v ...interface{})
	Warningln(v ...interface{})
	Infof(format string, v ...interface{})
	Infoln(v ...interface{})
	Requestln(v ...interface{})
	Panicln(v ...interface{})
	Panicf(format string, v ...interface{})
	Slackf(format string, v ...interface{})
	SlackLn(v ...interface{})
}

func (this *Logger) SetPrefix(prefix string) {

	if prefix != "" {
		prefix = prefix + " "
	}

	this.info.SetPrefix(prefix + "I: ")
	this.warning.SetPrefix(prefix + "W: ")
	this.error.SetPrefix(prefix + "E: ")
	this.slack.SetPrefix(prefix + "SLACK: ")
	this.request.SetPrefix(prefix + "R: ")
}

func (this *Logger) Errorf(format string, v ...interface{}) {
	this.error.Output(this.callDepth, f(format, v...))
}

func (this *Logger) Errorln(v ...interface{}) {
	this.error.Output(this.callDepth, ln(v...))
}

func (this *Logger) Warningf(format string, v ...interface{}) {
	this.warning.Output(this.callDepth, f(format, v...))
}

func (this *Logger) Warningln(v ...interface{}) {
	this.warning.Output(this.callDepth, ln(v...))
}

func (this *Logger) Infof(format string, v ...interface{}) {
	this.info.Output(this.callDepth, f(format, v...))
}

func (this *Logger) Infoln(v ...interface{}) {
	this.info.Output(this.callDepth, ln(v...))
}

func (this *Logger) Requestln(v ...interface{}) {
	this.request.Println(v...)
}

func (this *Logger) Panicln(v ...interface{}) {
	string := ln(v...)
	this.error.Output(this.callDepth, string)
	panic(string)
}

func (this *Logger) Panicf(format string, v ...interface{}) {
	string := f(format, v...)
	this.error.Output(this.callDepth, string)
	panic(string)
}

func (this *Logger) Slackf(format string, v ...interface{}) {
	this.slack.Output(this.callDepth, f(format, v...))
}

func (this *Logger) SlackLn(v ...interface{}) {
	this.slack.Output(this.callDepth, ln(v...))
}

//Globals
func Errorf(format string, v ...interface{}) {
	defaultLogger.Errorf(format, v...)
}

func Errorln(v ...interface{}) {
	defaultLogger.Errorln(v...)
}

func Warningf(format string, v ...interface{}) {
	defaultLogger.Warningf(format, v...)
}

func Warningln(v ...interface{}) {
	defaultLogger.Warningln(v...)
}

func Infof(format string, v ...interface{}) {
	defaultLogger.Infof(format, v...)
}

func Infoln(v ...interface{}) {
	defaultLogger.Infoln(v...)
}

func Requestln(v ...interface{}) {
	defaultLogger.Requestln(v...)
}

func Panicln(v ...interface{}) {
	defaultLogger.Panicln(v...)
}

func Panicf(format string, v ...interface{}) {
	defaultLogger.Panicf(format, v...)
}

func Slackf(format string, v ...interface{}) {
	defaultLogger.Slackf(format, v...)
}

func SlackLn(v ...interface{}) {
	defaultLogger.SlackLn(v...)
}

func SetPrefix(p string) {
	defaultLogger.SetPrefix(p)
}

func f(format string, v ...interface{}) string {
	return ln(fmt.Sprintf(format, v...))
}

func ln(a ...interface{}) string {
	return fmt.Sprintln(a...)
}
<commit_msg>structured logging object<commit_after>package log

import (
	"encoding/json"
	"fmt"
	"log"
	"os"
	"time"
)

type StructuredLog struct {
	Duration   time.Duration
	RemoteAddr string
	Referer    string
	Status     int
}

type Logger struct {
	info           *log.Logger
	warning        *log.Logger
	error          *log.Logger
	slack          *log.Logger
	request        *log.Logger
	requestEncoder *json.Encoder
	callDepth      int
}

func New(prefix string, depth int) *Logger {

	requestLogger := log.New(os.Stdout, "", log.Ldate|log.Ltime)
	l := &Logger{
		info:           log.New(os.Stdout, "", log.Ldate|log.Ltime|log.Lshortfile),
		warning:        log.New(os.Stdout, "", log.Ldate|log.Ltime|log.Lshortfile),
		error:          log.New(os.Stderr, "", log.Ldate|log.Ltime|log.Lshortfile),
		slack:          log.New(os.Stdout, "", log.Ldate|log.Ltime|log.Lshortfile),
		request:        requestLogger,
		requestEncoder: json.NewEncoder(os.Stdout),
		callDepth:      depth,
	}

	l.SetPrefix(prefix)
	return l
}

var defaultLogger = New("", 3)

type BLogger interface {
	Errorf(format string, v ...interface{})
	Errorln(v ...interface{})
	Warningf(format string, v ...interface{})
	Warningln(v ...interface{})
	Infof(format string, v ...interface{})
	Infoln(v ...interface{})
	Requestln(v ...interface{})
	Panicln(v ...interface{})
	Panicf(format string, v ...interface{})
	Slackf(format string, v ...interface{})
	SlackLn(v ...interface{})
}

func (this *Logger) SetPrefix(prefix string) {

	if prefix != "" {
		prefix = prefix + " "
	}

	this.info.SetPrefix(prefix + "I: ")
	this.warning.SetPrefix(prefix + "W: ")
	this.error.SetPrefix(prefix + "E: ")
	this.slack.SetPrefix(prefix + "SLACK: ")
	this.request.SetPrefix(prefix + "R: ")
}

func (this *Logger) Errorf(format string, v ...interface{}) {
	this.error.Output(this.callDepth, f(format, v...))
}

func (this *Logger) Errorln(v ...interface{}) {
	this.error.Output(this.callDepth, ln(v...))
}

func (this *Logger) Warningf(format string, v ...interface{}) {
	this.warning.Output(this.callDepth, f(format, v...))
}

func (this *Logger) Warningln(v ...interface{}) {
	this.warning.Output(this.callDepth, ln(v...))
}

func (this *Logger) Infof(format string, v ...interface{}) {
	this.info.Output(this.callDepth, f(format, v...))
}

func (this *Logger) Infoln(v ...interface{}) {
	this.info.Output(this.callDepth, ln(v...))
}

func (this *Logger) Requestln(v ...interface{}) {
	this.request.Println(v...)
}

func (this *Logger) RequestEncoder() *json.Encoder {
	return this.requestEncoder
}

func (this *Logger) Panicln(v ...interface{}) {
	string := ln(v...)
	this.error.Output(this.callDepth, string)
	panic(string)
}

func (this *Logger) Panicf(format string, v ...interface{}) {
	string := f(format, v...)
	this.error.Output(this.callDepth, string)
	panic(string)
}

func (this *Logger) Slackf(format string, v ...interface{}) {
	this.slack.Output(this.callDepth, f(format, v...))
}

func (this *Logger) SlackLn(v ...interface{}) {
	this.slack.Output(this.callDepth, ln(v...))
}

//Globals
func Errorf(format string, v ...interface{}) {
	defaultLogger.Errorf(format, v...)
}

func Errorln(v ...interface{}) {
	defaultLogger.Errorln(v...)
}

func Warningf(format string, v ...interface{}) {
	defaultLogger.Warningf(format, v...)
}

func Warningln(v ...interface{}) {
	defaultLogger.Warningln(v...)
}

func Infof(format string, v ...interface{}) {
	defaultLogger.Infof(format, v...)
}

func Infoln(v ...interface{}) {
	defaultLogger.Infoln(v...)
}

func Requestln(v ...interface{}) {
	defaultLogger.Requestln(v...)
}

func RequestObject(obj StructuredLog) {
	defaultLogger.requestEncoder.Encode(obj)
}

func Panicln(v ...interface{}) {
	defaultLogger.Panicln(v...)
}

func Panicf(format string, v ...interface{}) {
	defaultLogger.Panicf(format, v...)
}

func Slackf(format string, v ...interface{}) {
	defaultLogger.Slackf(format, v...)
}

func SlackLn(v ...interface{}) {
	defaultLogger.SlackLn(v...)
}

func SetPrefix(p string) {
	defaultLogger.SetPrefix(p)
}

func f(format string, v ...interface{}) string {
	return ln(fmt.Sprintf(format, v...))
}

func ln(a ...interface{}) string {
	return fmt.Sprintln(a...)
}
<|endoftext|>


<commit_before>// Package loglevel implements a simple levelled logging wrapper around the go
// "log" module
//
// The goal of this project is to be the simplest well-tested levelled logging
// wrapper around go's log module. It retains as much of the same API as possible.

package loglevel

import (
	"fmt"
	"io"
	"os"
	"strings"
)

var std = New(os.Stderr, "", LstdFlags, Pdebug)

// SetOutput sets the output destination for the standard logger
func SetOutput(out io.Writer) {
	std = New(out, std.Prefix(), std.Flags(), std.priority)
}

// Priority returns the output priority for the standard logger.
func Priority() int {
	return std.Priority()
}

// SetPriority sets the output priority for the standard logger.
func SetPriority(priority int) {
	std.SetPriority(priority)
}

// SetPriorityString sets the output priority by the name of a debug level
func SetPriorityString(s string) error {
	s = strings.ToUpper(s)
	for i, name := range priorityName {
		if name == s {
			SetPriority(i)
			return nil
		}
	}
	return fmt.Errorf("Unable to find priority %s", s)
}

// Flags returns the output layouts for the standard logger.
func Flags() int {
	return std.Flags()
}

// SetFlags sets the output layouts for the standard logger.
func SetFlags(flags int) {
	std.SetFlags(flags)
}

// SetPrefix sets the logger prefix
func SetPrefix(prefix string) {
	std.SetPrefix(prefix)
}

// Fatal prints the message it's given and quits the program
func Fatal(v ...interface{}) {
	std.Fatal(v...)
}

// Fatalf prints the message it's given and quits the program
func Fatalf(format string, v ...interface{}) {
	std.Fatalf(format, v...)
}

// Fatalln prints the message it's given and quits the program
func Fatalln(v ...interface{}) {
	std.Fatalln(v...)
}

// Panic prints the message it's given and panic()s the program
func Panic(v ...interface{}) {
	std.Panic(v...)
}

// Panicf prints the message it's given and panic()s the program
func Panicf(format string, v ...interface{}) {
	std.Panicf(format, v...)
}

// Panicln prints the message it's given and panic()s the program
func Panicln(v ...interface{}) {
	std.Panicln(v...)
}

// Error prints to the standard logger with the Error level.
func Error(v ...interface{}) {
	std.Error(v...)
}

// Errorf prints to the standard logger with the Error level.
func Errorf(format string, v ...interface{}) {
	std.Errorf(format, v...)
}

// Errorln prints to the standard logger with the Error level.
func Errorln(v ...interface{}) {
	std.Errorln(v...)
}

// Warn prints to the standard logger with the Warn level.
func Warn(v ...interface{}) {
	std.Warn(v...)
}

// Warnf prints to the standard logger with the Warn level.
func Warnf(format string, v ...interface{}) {
	std.Warnf(format, v...)
}

// Warnln prints to the standard logger with the Warn level.
func Warnln(v ...interface{}) {
	std.Warnln(v...)
}

// Info prints to the standard logger with the Info level.
func Info(v ...interface{}) {
	std.Info(v...)
}

// Infof prints to the standard logger with the Info level.
func Infof(format string, v ...interface{}) {
	std.Infof(format, v...)
}

// Infoln prints to the standard logger with the Info level.
func Infoln(v ...interface{}) {
	std.Infoln(v...)
}

// Debug prints to the standard logger with the Debug level.
func Debug(v ...interface{}) {
	std.Debug(v...)
}

// Debugf prints to the standard logger with the Debug level.
func Debugf(format string, v ...interface{}) {
	std.Debugf(format, v...)
}

// Debugln prints to the standard logger with the Debug level.
func Debugln(v ...interface{}) {
	std.Debugln(v...)
}

// Trace prints to the standard logger with the Trace level.
func Trace(v ...interface{}) {
	std.Trace(v...)
}

// Tracef prints to the standard logger with the Trace level.
func Tracef(format string, v ...interface{}) {
	std.Tracef(format, v...)
}

// Traceln prints to the standard logger with the Trace level.
func Traceln(v ...interface{}) {
	std.Traceln(v...)
}
<commit_msg>Remove space that killed package docstring<commit_after>// Package loglevel implements a simple levelled logging wrapper around the go
// "log" module
//
// The goal of this project is to be the simplest well-tested levelled logging
// wrapper around go's log module. It retains as much of the same API as possible.
package loglevel

import (
	"fmt"
	"io"
	"os"
	"strings"
)

var std = New(os.Stderr, "", LstdFlags, Pdebug)

// SetOutput sets the output destination for the standard logger
func SetOutput(out io.Writer) {
	std = New(out, std.Prefix(), std.Flags(), std.priority)
}

// Priority returns the output priority for the standard logger.
func Priority() int {
	return std.Priority()
}

// SetPriority sets the output priority for the standard logger.
func SetPriority(priority int) {
	std.SetPriority(priority)
}

// SetPriorityString sets the output priority by the name of a debug level
func SetPriorityString(s string) error {
	s = strings.ToUpper(s)
	for i, name := range priorityName {
		if name == s {
			SetPriority(i)
			return nil
		}
	}
	return fmt.Errorf("Unable to find priority %s", s)
}

// Flags returns the output layouts for the standard logger.
func Flags() int {
	return std.Flags()
}

// SetFlags sets the output layouts for the standard logger.
func SetFlags(flags int) {
	std.SetFlags(flags)
}

// SetPrefix sets the logger prefix
func SetPrefix(prefix string) {
	std.SetPrefix(prefix)
}

// Fatal prints the message it's given and quits the program
func Fatal(v ...interface{}) {
	std.Fatal(v...)
}

// Fatalf prints the message it's given and quits the program
func Fatalf(format string, v ...interface{}) {
	std.Fatalf(format, v...)
}

// Fatalln prints the message it's given and quits the program
func Fatalln(v ...interface{}) {
	std.Fatalln(v...)
}

// Panic prints the message it's given and panic()s the program
func Panic(v ...interface{}) {
	std.Panic(v...)
}

// Panicf prints the message it's given and panic()s the program
func Panicf(format string, v ...interface{}) {
	std.Panicf(format, v...)
}

// Panicln prints the message it's given and panic()s the program
func Panicln(v ...interface{}) {
	std.Panicln(v...)
}

// Error prints to the standard logger with the Error level.
func Error(v ...interface{}) {
	std.Error(v...)
}

// Errorf prints to the standard logger with the Error level.
func Errorf(format string, v ...interface{}) {
	std.Errorf(format, v...)
}

// Errorln prints to the standard logger with the Error level.
func Errorln(v ...interface{}) {
	std.Errorln(v...)
}

// Warn prints to the standard logger with the Warn level.
func Warn(v ...interface{}) {
	std.Warn(v...)
}

// Warnf prints to the standard logger with the Warn level.
func Warnf(format string, v ...interface{}) {
	std.Warnf(format, v...)
}

// Warnln prints to the standard logger with the Warn level.
func Warnln(v ...interface{}) {
	std.Warnln(v...)
}

// Info prints to the standard logger with the Info level.
func Info(v ...interface{}) {
	std.Info(v...)
}

// Infof prints to the standard logger with the Info level.
func Infof(format string, v ...interface{}) {
	std.Infof(format, v...)
}

// Infoln prints to the standard logger with the Info level.
func Infoln(v ...interface{}) {
	std.Infoln(v...)
}

// Debug prints to the standard logger with the Debug level.
func Debug(v ...interface{}) {
	std.Debug(v...)
}

// Debugf prints to the standard logger with the Debug level.
func Debugf(format string, v ...interface{}) {
	std.Debugf(format, v...)
}

// Debugln prints to the standard logger with the Debug level.
func Debugln(v ...interface{}) {
	std.Debugln(v...)
}

// Trace prints to the standard logger with the Trace level.
func Trace(v ...interface{}) {
	std.Trace(v...)
}

// Tracef prints to the standard logger with the Trace level.
func Tracef(format string, v ...interface{}) {
	std.Tracef(format, v...)
}

// Traceln prints to the standard logger with the Trace level.
func Traceln(v ...interface{}) {
	std.Traceln(v...)
}
<|endoftext|>


<commit_before>package main

import (
	"code.google.com/p/go9p/p"
	"code.google.com/p/go9p/p/srv"
	"strings"
	"bytes"
	"flag"
	"fmt"
	"os"
	"strconv"
	"unicode/utf8"
)

type M9Player struct {
	playlist []string
	position int
	queue []string

	player *os.Process
	song *string
}

var m9 *M9Player

func (m9 *M9Player) spawn(song string) {
	player, err := os.StartProcess("/bin/echo", []string{"m9play", song}, new(os.ProcAttr))
	if err != nil {
		fmt.Printf("couldn't spawn player: %s\n", err)
		return
	}
	m9.player = player
	m9.song = &song
	events <- "Play " + song
	go func() {
		player.Wait()
		if len(m9.queue) == 0 && len(m9.playlist) > 0 {
			m9.position = (m9.position + 1) % len(m9.playlist)
		}
		m9.song = nil
		if m9.player != nil {
			m9.player = nil
			m9.Play("")
		}
	}()
}

func (m9 *M9Player) state() string {
	var s string
	if m9.player == nil {
		s = "Stop"
	} else {
		s = "Play"
	}

	if m9.song != nil {
		return s + " " + *m9.song
	} else if len(m9.queue) > 0 {
		return s + " " + m9.queue[0]
	} else if len(m9.playlist) > 0 {
		return s + " " + m9.playlist[m9.position]
	}
	return s
}

func (m9 *M9Player) Add(song string) {
	m9.playlist = append(m9.playlist, song)
}

func (m9 *M9Player) Clear() {
	m9.playlist = make([]string, 0)
}

func (m9 *M9Player) Enqueue(song string) {
	m9.queue = append(m9.queue, song)
}

func (m9 *M9Player) Play(song string) {
	player := m9.player
	if player != nil {
		/* already playing; stop the current player first */
		m9.player = nil
		player.Kill()
	}
	if song != "" {
		m9.spawn(song)
	} else {
		if len(m9.queue) > 0 {
			m9.spawn(m9.queue[0])
			m9.queue = m9.queue[1:]
		} else if len(m9.playlist) > 0 {
			m9.spawn(m9.playlist[m9.position])
		}
	}
}

func (m9 *M9Player) Skip(n int) {
	if len(m9.playlist) == 0 {
		return
	}
	m9.position += n
	m9.position %= len(m9.playlist)
	if m9.position < 0 {
		m9.position += len(m9.playlist)
	}
	if m9.player != nil {
		m9.Play("")
	} else {
		events <- m9.state()
	}
}

func (m9 *M9Player) Stop() {
	player := m9.player
	m9.player = nil
	if player != nil {
		player.Kill()
	}
	events <- m9.state()
}

func play(song string) {
	fmt.Printf("play: %s\n", song)
	m9.Play(song)
}

func skip(amount string) error {
	i, err := strconv.Atoi(amount)
	if err != nil {
		return err
	}
	m9.Skip(i)
	return nil
}

func stop() {
	fmt.Printf("stop:\n")
	m9.Stop()
}

var events chan string
var register chan chan string

func eventer() {
	listeners := make([]chan string, 0)
	for {
		select {
		case ev := <- events:
			for i := range(listeners) {
				listeners[i] <- ev
			}
			listeners = make([]chan string, 0)

		case l := <- register:
			listeners = append(listeners, l)
		}
	}
}

func waitForEvent() string {
	c := make(chan string)
	register <- c
	ev := <- c
	return ev
}

var addr = flag.String("addr", ":5640", "network address")

type CtlFile struct {
	srv.File
}
type SongListFile struct {
	srv.File
	rd map[*srv.Fid] []byte
	wr map[*srv.Fid] *PartialLine
	SongAdded func(string)
}
type ListFile struct {
	SongListFile
}
type QueueFile struct {
	SongListFile
}
type EventFile struct {
	srv.File
}

func (*CtlFile) Write(fid *srv.FFid, b []byte, offset uint64) (n int, err error) {
	cmd := string(b)
	fmt.Printf("write:  %s\n", cmd)
	if strings.HasPrefix(cmd, "play") {
		play(strings.Trim(cmd[4:], " \n"))
	} else if strings.HasPrefix(cmd, "skip") {
		err = skip(strings.Trim(cmd[4:], " \n"))
	} else if strings.HasPrefix(cmd, "stop") {
		stop()
	} else {
		err = m9err("/ctl", "write", "syntax error")
	}
	if err == nil {
		n = len(b)
	}
	return n, err
}

func mkbuf(lst []string) []byte {
	buflen := 0
	for i := range(lst) {
		buflen += 1 + len([]byte(lst[i]))
	}
	buf := make([]byte, buflen)
	j := 0
	for i := range(lst) {
		j += copy(buf[j:], lst[i])
		buf[j] = '\n'
		j++
	}
	return buf
}

type PartialLine struct {
	leftover []byte
}

func (part *PartialLine) append(bytes []byte) string {
	if part.leftover == nil {
		return string(bytes)
	}
	left := part.leftover
	part.leftover = nil
	return string(left) + string(bytes)
}

func (lstfile *ListFile) Open(fid *srv.FFid, mode uint8) error {
	if mode & 3 == p.OWRITE || mode & 3 == p.ORDWR {
		lstfile.wr[fid.Fid] = new(PartialLine)
		if mode & p.OTRUNC != 0 {
			m9.Clear()
		}
	}
	if mode & 3 == p.OREAD || mode & 3 == p.ORDWR {
		lstfile.rd[fid.Fid] = mkbuf(m9.playlist)
	}
	return nil
}

type M9Error struct {
	file string
	op string
	msg string
}

func (e *M9Error) Error() string {
	return e.file + ": " + e.op + ": " + e.msg
}

func m9err(file string, op string, msg string) *M9Error {
	err := new(M9Error)
	err.file = file
	err.op = op
	err.msg = msg
	return err
}

func (slf *SongListFile) Write(fid *srv.FFid, b []byte, offset uint64) (int, error) {
	prefix, ok := slf.wr[fid.Fid]
	if !ok {
		return 0, m9err(fid.F.Name, "write", "bad state")
	}
	i := 0
	for {
		j := bytes.IndexByte(b[i:], '\n')
		if j == -1 {
			break
		}
		song := prefix.append(b[i:j])
		slf.SongAdded(song)
		//m9.Add(song)
		i = j+1
	}
	if i < len(b) {
		prefix.leftover = b[i:]
	}
	return len(b), nil
}

func min(a uint64, b uint64) uint64 {
	if a < b {
		return a
	}
	return b
}

func (slf *SongListFile) Read(fid *srv.FFid, b []byte, offset uint64) (int, error) {
	buf, ok := slf.rd[fid.Fid]
	if !ok {
		return 0, m9err(fid.F.Name, "read", "bad state")
	}
	remaining := uint64(len(buf)) - offset
	n := min(remaining, uint64(len(b)))
	copy(b, buf[offset:offset + n])
	return int(n), nil
}

func (slf *SongListFile) Clunk(fid *srv.FFid) error {
	delete(slf.rd, fid.Fid)
	delete(slf.wr, fid.Fid)
	return nil
}

func (qf *QueueFile) Open(fid *srv.FFid, mode uint8) error {
	if mode & 3 == p.OWRITE || mode & 3 == p.ORDWR {
		qf.wr[fid.Fid] = new(PartialLine)
	}
	if mode & 3 == p.OREAD || mode & 3 == p.ORDWR {
		qf.rd[fid.Fid] = mkbuf(m9.queue)
	}
	return nil
}

func (*EventFile) Read(fid *srv.FFid, b []byte, offset uint64) (int, error) {
	var ev string
	if offset == 0 {
		ev = m9.state()
	} else {
		ev = waitForEvent()
	}
	buf := []byte(ev)
	for len(buf) > len(b) - 1 {
		_, size := utf8.DecodeLastRune(buf)
		buf = buf[:len(buf)-size]
	}
	copy(b[:len(buf)], buf)
	b[len(buf)] = byte('\n')
	return len(buf)+1, nil
}

func (slf *SongListFile) init(f func(string)) {
	slf.wr = make(map[*srv.Fid]*PartialLine)
	slf.rd = make(map[*srv.Fid] []byte)
	slf.SongAdded = f
}

func main() {
	var err error

	uid := p.OsUsers.Uid2User(os.Geteuid())
	gid := p.OsUsers.Gid2Group(os.Getegid())
	fmt.Printf("uid = %d  gid = %d\n", os.Geteuid(), os.Getegid())

	events = make(chan string)
	register = make(chan chan string)

	m9 = new(M9Player)

	go eventer()

	root := new(srv.File)
	root.Add(nil, "/", uid, gid, p.DMDIR|0555, nil)
	ctl := new(CtlFile)
	ctl.Add(root, "ctl", uid, gid, 0644, ctl)
	list := new(ListFile)
	list.init(func(song string) {m9.Add(song)})
	list.Add(root, "list", uid, gid, 0644, list)
	queue := new(QueueFile)
	queue.init(func(song string) {m9.Enqueue(song)})
	queue.Add(root, "queue", uid, gid, 0644, queue)
	event := new(EventFile)
	event.Add(root, "event", uid, gid, 0444, event)

	s := srv.NewFileSrv(root)
	s.Start(s)
	err = s.StartNetListener("tcp", *addr)
	if err != nil {
		fmt.Printf("Error: %s\n", err)
	}

	return
}

<commit_msg>Add flags. Fix /list write bug. Default skip to 1.<commit_after>package main

import (
	"code.google.com/p/go9p/p"
	"code.google.com/p/go9p/p/srv"
	"strings"
	"bytes"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"sync"
	"strconv"
	"unicode/utf8"
)

type M9Player struct {
	playlist []string
	position int
	queue []string

	player *os.Process
	song *string
}

var m9 *M9Player

func (m9 *M9Player) spawn(song string) {
	path, err := exec.LookPath("m9play")
	if err != nil {
		fmt.Printf("couldn't find m9play: %s\n", err)
		return
	}
	player, err := os.StartProcess(path, []string{"m9play", song}, new(os.ProcAttr))
	if err != nil {
		fmt.Printf("couldn't spawn player: %s\n", err)
		return
	}
	m9.player = player
	m9.song = &song
	events <- "Play " + song
	go func() {
		player.Wait()
		if len(m9.queue) == 0 && len(m9.playlist) > 0 {
			m9.position = (m9.position + 1) % len(m9.playlist)
		}
		m9.song = nil
		if m9.player != nil {
			m9.player = nil
			m9.Play("")
		}
	}()
}

func (m9 *M9Player) state() string {
	var s string
	if m9.player == nil {
		s = "Stop"
	} else {
		s = "Play"
	}

	if m9.song != nil {
		return s + " " + *m9.song
	} else if len(m9.queue) > 0 {
		return s + " " + m9.queue[0]
	} else if len(m9.playlist) > 0 {
		return s + " " + m9.playlist[m9.position]
	}
	return s
}

func (m9 *M9Player) Add(song string) {
	m9.playlist = append(m9.playlist, song)
}

func (m9 *M9Player) Clear() {
	m9.playlist = make([]string, 0)
}

func (m9 *M9Player) Enqueue(song string) {
	m9.queue = append(m9.queue, song)
}

func (m9 *M9Player) Play(song string) {
	player := m9.player
	if player != nil {
		/* already playing; stop the current player first */
		m9.player = nil
		player.Kill()
	}
	if song != "" {
		m9.spawn(song)
	} else {
		if len(m9.queue) > 0 {
			m9.spawn(m9.queue[0])
			m9.queue = m9.queue[1:]
		} else if len(m9.playlist) > 0 {
			m9.spawn(m9.playlist[m9.position])
		}
	}
}

func (m9 *M9Player) Skip(n int) {
	if len(m9.playlist) == 0 {
		return
	}
	m9.position += n
	m9.position %= len(m9.playlist)
	if m9.position < 0 {
		m9.position += len(m9.playlist)
	}
	if m9.player != nil {
		m9.Play("")
	} else {
		events <- m9.state()
	}
}

func (m9 *M9Player) Stop() {
	player := m9.player
	m9.player = nil
	if player != nil {
		player.Kill()
	}
	events <- m9.state()
}

func play(song string) {
	fmt.Printf("play: %s\n", song)
	m9.Play(song)
}

func skip(amount string) error {
	if amount == "" {
		m9.Skip(1)
		return nil
	}
	i, err := strconv.Atoi(amount)
	if err != nil {
		return err
	}
	m9.Skip(i)
	return nil
}

func stop() {
	fmt.Printf("stop:\n")
	m9.Stop()
}

var events chan string
var register chan chan string

func eventer() {
	listeners := make([]chan string, 0)
	for {
		select {
		case ev := <- events:
			for i := range(listeners) {
				listeners[i] <- ev
			}
			listeners = make([]chan string, 0)

		case l := <- register:
			listeners = append(listeners, l)
		}
	}
}

func waitForEvent() string {
	c := make(chan string)
	register <- c
	ev := <- c
	return ev
}

var net = flag.String("net", "unix", "network type")
var addr = flag.String("addr", "/tmp/ns.sqweek.:0/m9u", "network address")

type CtlFile struct {
	srv.File
}
type SongListFile struct {
	srv.File
	rd map[*srv.Fid] []byte
	wr map[*srv.Fid] *PartialLine
	SongAdded func(string)
}
type ListFile struct {
	SongListFile
}
type QueueFile struct {
	SongListFile
}
type EventFile struct {
	srv.File
}

func (*CtlFile) Write(fid *srv.FFid, b []byte, offset uint64) (n int, err error) {
	cmd := string(b)
	fmt.Printf("write:  %s\n", cmd)
	if strings.HasPrefix(cmd, "play") {
		play(strings.Trim(cmd[4:], " \n"))
	} else if strings.HasPrefix(cmd, "skip") {
		err = skip(strings.Trim(cmd[4:], " \n"))
	} else if strings.HasPrefix(cmd, "stop") {
		stop()
	} else {
		err = m9err("/ctl", "write", "syntax error")
	}
	if err == nil {
		n = len(b)
	}
	return n, err
}

func mkbuf(lst []string) []byte {
	buflen := 0
	for i := range(lst) {
		buflen += 1 + len([]byte(lst[i]))
	}
	buf := make([]byte, buflen)
	j := 0
	for i := range(lst) {
		j += copy(buf[j:], lst[i])
		buf[j] = '\n'
		j++
	}
	return buf
}

type PartialLine struct {
	leftover []byte
}

func (part *PartialLine) append(bytes []byte) string {
	if part.leftover == nil {
		return string(bytes)
	}
	left := part.leftover
	part.leftover = nil
	return string(left) + string(bytes)
}

func (lstfile *ListFile) Open(fid *srv.FFid, mode uint8) error {
	if mode & 3 == p.OWRITE || mode & 3 == p.ORDWR {
		lstfile.wr[fid.Fid] = new(PartialLine)
		if mode & p.OTRUNC != 0 {
			m9.Clear()
		}
	}
	if mode & 3 == p.OREAD || mode & 3 == p.ORDWR {
		lstfile.rd[fid.Fid] = mkbuf(m9.playlist)
	}
	return nil
}

type M9Error struct {
	file string
	op string
	msg string
}

func (e *M9Error) Error() string {
	return e.file + ": " + e.op + ": " + e.msg
}

func m9err(file string, op string, msg string) *M9Error {
	err := new(M9Error)
	err.file = file
	err.op = op
	err.msg = msg
	return err
}

func (slf *SongListFile) Write(fid *srv.FFid, b []byte, offset uint64) (int, error) {
	prefix, ok := slf.wr[fid.Fid]
	if !ok {
		return 0, m9err(fid.F.Name, "write", "bad state")
	}
	i := 0
	for {
		j := bytes.IndexByte(b[i:], '\n')
		if j == -1 {
			break
		}
		song := prefix.append(b[i:i+j])
		slf.SongAdded(song)
		//m9.Add(song)
		i += j+1
	}
	if i < len(b) {
		prefix.leftover = b[i:]
	}
	return len(b), nil
}

func min(a uint64, b uint64) uint64 {
	if a < b {
		return a
	}
	return b
}

func (slf *SongListFile) Read(fid *srv.FFid, b []byte, offset uint64) (int, error) {
	buf, ok := slf.rd[fid.Fid]
	if !ok {
		return 0, m9err(fid.F.Name, "read", "bad state")
	}
	remaining := uint64(len(buf)) - offset
	n := min(remaining, uint64(len(b)))
	copy(b, buf[offset:offset + n])
	return int(n), nil
}

func (slf *SongListFile) Clunk(fid *srv.FFid) error {
	delete(slf.rd, fid.Fid)
	delete(slf.wr, fid.Fid)
	return nil
}

func (qf *QueueFile) Open(fid *srv.FFid, mode uint8) error {
	if mode & 3 == p.OWRITE || mode & 3 == p.ORDWR {
		qf.wr[fid.Fid] = new(PartialLine)
	}
	if mode & 3 == p.OREAD || mode & 3 == p.ORDWR {
		qf.rd[fid.Fid] = mkbuf(m9.queue)
	}
	return nil
}

func (*EventFile) Read(fid *srv.FFid, b []byte, offset uint64) (int, error) {
	var ev string
	if offset == 0 {
		ev = m9.state()
	} else {
		ev = waitForEvent()
	}
	buf := []byte(ev)
	for len(buf) > len(b) - 1 {
		_, size := utf8.DecodeLastRune(buf)
		buf = buf[:len(buf)-size]
	}
	copy(b[:len(buf)], buf)
	b[len(buf)] = byte('\n')
	return len(buf)+1, nil
}

func (slf *SongListFile) init(f func(string)) {
	slf.wr = make(map[*srv.Fid]*PartialLine)
	slf.rd = make(map[*srv.Fid] []byte)
	slf.SongAdded = f
}

func main() {
	var err error
	flag.Parse()

	uid := p.OsUsers.Uid2User(os.Geteuid())
	gid := p.OsUsers.Gid2Group(os.Getegid())
	fmt.Printf("uid = %d  gid = %d\n", os.Geteuid(), os.Getegid())

	events = make(chan string)
	register = make(chan chan string)

	m9 = new(M9Player)

	go eventer()

	root := new(srv.File)
	root.Add(nil, "/", uid, gid, p.DMDIR|0555, nil)
	ctl := new(CtlFile)
	ctl.Add(root, "ctl", uid, gid, 0644, ctl)
	list := new(ListFile)
	list.init(func(song string) {m9.Add(song)})
	list.Add(root, "list", uid, gid, 0644, list)
	queue := new(QueueFile)
	queue.init(func(song string) {m9.Enqueue(song)})
	queue.Add(root, "queue", uid, gid, 0644, queue)
	event := new(EventFile)
	event.Add(root, "event", uid, gid, 0444, event)

	s := srv.NewFileSrv(root)
	s.Start(s)
	err = s.StartNetListener(*net, *addr)
	if err != nil {
		fmt.Printf("Error: %s\n", err)
	}

	return
}

<|endoftext|>


<commit_before>// Fully persistent data structures. A persistent data structure is a data
// structure that always preserves the previous version of itself when
// it is modified. Such data structures are effectively immutable,
// as their operations do not update the structure in-place, but instead
// always yield a new structure.
//
// Persistent
// data structures typically share structure among themselves.  This allows
// operations to avoid copying the entire data structure.
package ps

import . "fmt"

import "bytes"

// Any is a shorthand for Go's verbose interface{} type.
type Any interface{}

// A Map associates unique keys (type string) with values (type Any).
type Map interface {
    // IsNil returns true if the Map is empty
    IsNil() bool

    // Set returns a new map in which key and value are associated.
    // If the key didn't exist before, it's created; otherwise, the
    // associated value is changed.
    // This operation is O(log N) in the number of keys.
    Set(key string, value Any) Map

    // Delete returns a new map with the association for key, if any, removed.
    // This operation is O(log N) in the number of keys.
    Delete(key string) Map

    // Lookup returns the value associated with a key, if any.  If the key
    // exists, the second return value is true; otherwise, false.
    // This operation is O(log N) in the number of keys.
    Lookup(key string) (Any, bool)

    // Size returns the number of key value pairs in the map.
    // This takes O(1) time.
    Size() int

    // ForEach executes a callback on each key value pair in the map.
    ForEach(f func(key string, val Any))

    // Keys returns a slice with all keys in this map.
    // This operation is O(N) in the number of keys.
    Keys() []string

    String() string
}

// Immutable (i.e. persistent) associative array
type tree struct {
    count   int
    hash    uint64  // hash of the key (used for tree balancing)
    key     string
    value   Any
    left    *tree
    right   *tree
}
var nilMap = &tree{}

// Recursively set nilMap's subtrees to point at itself.
// This eliminates all nil pointers in the map structure.
// All map nodes are created by cloning this structure so
// they avoid the problem too.
func init () {
    nilMap.left = nilMap
    nilMap.right = nilMap
}

// NewMap allocates a new, persistent map from strings to values of
// any type.
// This is currently implemented as a path-copying binary tree.
func NewMap() Map {
    return nilMap
}

func (self *tree) IsNil() bool {
    return self == nilMap
}

// clone returns an exact duplicate of a tree node
func (self *tree) clone() *tree {
    var m tree
    m = *self
    return &m
}

// constants for FNV-1a hash algorithm
const (
    offset64 uint64 = 14695981039346656037
    prime64  uint64 = 1099511628211
)
// hashKey returns a hash code for a given string
func hashKey(key string) uint64 {
    bytes := []byte(key)
    hash := offset64
    for _, byte := range bytes {
        hash ^= uint64(byte)
        hash *= prime64
    }
    return hash
}

// Set returns a new map similar to this one but with key and value
// associated.  If the key didn't exist, it's created; otherwise, the
// associated value is changed.
func (self *tree) Set(key string, value Any) Map {
    hash := hashKey(key)
    return setLowLevel(self, hash, key, value)
}

func setLowLevel(self *tree, hash uint64, key string, value Any) *tree {
    if self.IsNil() { // an empty tree is easy
        m := self.clone()
        m.count = 1
        m.hash  = hash
        m.key   = key
        m.value = value
        return m
    }

    if hash < self.hash { // insert into left subtree
        m := self.clone()
        m.left = setLowLevel(self.left, hash, key, value)
        recalculateCount(m)
        return m
    }
    if hash > self.hash { // insert into right subtree
        m := self.clone()
        m.right = setLowLevel(self.right, hash, key, value)
        recalculateCount(m)
        return m
    }

    // replacing a key's previous value
    m := self.clone()
    m.value = value
    return m
}

// modifies a map by recalculating its key count based on the counts
// of its subtrees
func recalculateCount(m *tree) {
    count := 0
    if !m.left.IsNil() {
        count += m.left.Size()
    }
    if !m.right.IsNil() {
        count += m.right.Size()
    }
    m.count = count + 1 // add one to count ourself
}

func (m *tree) Delete(key string) Map {
    hash := hashKey(key)
    newMap, _ := deleteLowLevel(m, hash)
    return newMap
}

func deleteLowLevel(self *tree, hash uint64) (*tree, bool) {
    // empty trees are easy
    if self.IsNil() {
        return self, false
    }

    if hash < self.hash { // look in the left subtree
        newLeft, found := deleteLowLevel(self.left, hash)
        if !found {
            return self, false
        }
        newMap := self.clone()
        newMap.left = newLeft
        recalculateCount(newMap)
    }
    if hash > self.hash { // look in the right subtree
        newRight, found := deleteLowLevel(self.right, hash)
        if !found {
            return self, false
        }
        newMap := self.clone()
        newMap.right = newRight
        recalculateCount(newMap)
    }

    // we must delete our own node
    if self.isLeaf() {  // we have no children
        return nilMap, true
    }
    if self.subtreeCount() == 1 { // only one subtree
        if self.hasLeft() {  // it's the left one
            return self.left, true
        }
        return self.right, true  // it's the right one
    }

    // find a node to replace us
    if self.left.Size() > self.right.Size() {  // make left side smaller
        replacement, newLeft := self.left.deleteRightmost()
        newMap := replacement.clone()
        newMap.left = newLeft
        newMap.right = self.right
        recalculateCount(newMap)
        return newMap, true
    }

    // make right side smaller
    replacement, newRight := self.right.deleteLeftmost()
    newMap := replacement.clone()
    newMap.right = newRight
    newMap.left = self.left
    recalculateCount(newMap)
    return newMap, true
}

// delete the left or rightmost node in a tree returning the node that
// was deleted and the tree left over after its deletion
func (m *tree) deleteRightmost() (*tree, *tree) {
    if m.isLeaf() {
        return m, nilMap
    }
    if m.hasRight() {
        deleted, newRight := m.right.deleteRightmost()
        newMap := m.clone()
        newMap.right = newRight
        recalculateCount(newMap)
        return deleted, newMap
    }

    deleted := m.clone()
    deleted.left = nilMap
    return deleted, m.left
}
func (m *tree) deleteLeftmost() (*tree, *tree) {
    if m.isLeaf() {
        return m, nilMap
    }
    if m.hasLeft() {
        deleted, newLeft := m.left.deleteLeftmost()
        newMap := m.clone()
        newMap.left = newLeft
        recalculateCount(newMap)
        return deleted, newMap
    }

    deleted := m.clone()
    deleted.count = 1
    deleted.right = nilMap
    return deleted, m.right
}

// hasLeft and hasRight return true if this tree has a left or right subtree
func (m *tree) hasLeft() bool {
    return !m.left.IsNil()
}
func (m *tree) hasRight() bool {
    return !m.right.IsNil()
}

// isLeaf returns true if this is a leaf node
func (m *tree) isLeaf() bool {
    return m.Size() == 1
}

// returns the number of child subtrees we have
func (m *tree) subtreeCount() int {
    count := 0
    if m.hasLeft() {
        count++
    }
    if m.hasRight() {
        count++
    }
    return count
}

func (m *tree) Lookup(key string) (Any, bool) {
    hash := hashKey(key)
    return lookupLowLevel(m, hash)
}

func lookupLowLevel(self *tree, hash uint64) (Any, bool) {
    if self.IsNil() { // an empty tree is easy
        return nil, false
    }

    if hash < self.hash { // look in the left subtree
        return lookupLowLevel(self.left, hash)
    }
    if hash > self.hash { // look in the right subtree
        return lookupLowLevel(self.right, hash)
    }

    // we found it
    return self.value, true
}

func (m *tree) Size() int {
    return m.count
}

func (m *tree) ForEach(f func(key string, val Any)) {
    if m.IsNil() {
        return
    }

    // left branch
    if !m.left.IsNil() {
        m.left.ForEach(f)
    }

    // ourself
    f(m.key, m.value)

    // right branch
    if !m.right.IsNil() {
        m.right.ForEach(f)
    }
}

func (m *tree) Keys() []string {
    keys := make([]string, m.Size())
    i := 0
    m.ForEach( func (k string, v Any) {
        keys[i] = k
        i++
    })
    return keys
}

// make it easier to display maps for debugging
func (m *tree) String() string {
    keys := m.Keys()
    buf := bytes.NewBufferString("{")
    for _, key := range keys {
        val, _ := m.Lookup(key)
        Fprintf(buf, "%s: %s, ", key, val)
    }
    Fprintf(buf, "}\n")
    return buf.String()
}
<commit_msg>Use array of children for each node<commit_after>// Fully persistent data structures. A persistent data structure is a data
// structure that always preserves the previous version of itself when
// it is modified. Such data structures are effectively immutable,
// as their operations do not update the structure in-place, but instead
// always yield a new structure.
//
// Persistent
// data structures typically share structure among themselves.  This allows
// operations to avoid copying the entire data structure.
package ps

import . "fmt"

import "bytes"

// Any is a shorthand for Go's verbose interface{} type.
type Any interface{}

// A Map associates unique keys (type string) with values (type Any).
type Map interface {
    // IsNil returns true if the Map is empty
    IsNil() bool

    // Set returns a new map in which key and value are associated.
    // If the key didn't exist before, it's created; otherwise, the
    // associated value is changed.
    // This operation is O(log N) in the number of keys.
    Set(key string, value Any) Map

    // Delete returns a new map with the association for key, if any, removed.
    // This operation is O(log N) in the number of keys.
    Delete(key string) Map

    // Lookup returns the value associated with a key, if any.  If the key
    // exists, the second return value is true; otherwise, false.
    // This operation is O(log N) in the number of keys.
    Lookup(key string) (Any, bool)

    // Size returns the number of key value pairs in the map.
    // This takes O(1) time.
    Size() int

    // ForEach executes a callback on each key value pair in the map.
    ForEach(f func(key string, val Any))

    // Keys returns a slice with all keys in this map.
    // This operation is O(N) in the number of keys.
    Keys() []string

    String() string
}

// Immutable (i.e. persistent) associative array
const childCount = 2
const shiftSize  = 1
type tree struct {
    count   int
    hash    uint64  // hash of the key (used for tree balancing)
    key     string
    value   Any
    children  [childCount]*tree
}
var nilMap = &tree{}

// Recursively set nilMap's subtrees to point at itself.
// This eliminates all nil pointers in the map structure.
// All map nodes are created by cloning this structure so
// they avoid the problem too.
func init () {
    for i := range nilMap.children {
        nilMap.children[i] = nilMap
    }
}

// NewMap allocates a new, persistent map from strings to values of
// any type.
// This is currently implemented as a path-copying binary tree.
func NewMap() Map {
    return nilMap
}

func (self *tree) IsNil() bool {
    return self == nilMap
}

// clone returns an exact duplicate of a tree node
func (self *tree) clone() *tree {
    var m tree
    m = *self
    return &m
}

// constants for FNV-1a hash algorithm
const (
    offset64 uint64 = 14695981039346656037
    prime64  uint64 = 1099511628211
)
// hashKey returns a hash code for a given string
func hashKey(key string) uint64 {
    bytes := []byte(key)
    hash := offset64
    for _, byte := range bytes {
        hash ^= uint64(byte)
        hash *= prime64
    }
    return hash
}

// Set returns a new map similar to this one but with key and value
// associated.  If the key didn't exist, it's created; otherwise, the
// associated value is changed.
func (self *tree) Set(key string, value Any) Map {
    hash := hashKey(key)
    return setLowLevel(self, hash, hash, key, value)
}

func setLowLevel(self *tree, partialHash, hash uint64, key string, value Any) *tree {
    if self.IsNil() { // an empty tree is easy
        m := self.clone()
        m.count = 1
        m.hash  = hash
        m.key   = key
        m.value = value
        return m
    }

    if hash != self.hash {
        m := self.clone()
        i := partialHash % childCount
        m.children[i] = setLowLevel(self.children[i], partialHash>>shiftSize, hash, key, value)
        recalculateCount(m)
        return m
    }

    // replacing a key's previous value
    m := self.clone()
    m.value = value
    return m
}

// modifies a map by recalculating its key count based on the counts
// of its subtrees
func recalculateCount(m *tree) {
    count := 0
    for _, t := range m.children {
        count += t.Size()
    }
    m.count = count + 1 // add one to count ourself
}

func (m *tree) Delete(key string) Map {
    hash := hashKey(key)
    newMap, _ := deleteLowLevel(m, hash, hash)
    return newMap
}

func deleteLowLevel(self *tree, partialHash, hash uint64) (*tree, bool) {
    // empty trees are easy
    if self.IsNil() {
        return self, false
    }

    if hash != self.hash {
        i := partialHash % childCount
        child, found := deleteLowLevel(self.children[i], partialHash>>shiftSize, hash)
        if !found {
            return self, false
        }
        newMap := self.clone()
        newMap.children[i] = child
        recalculateCount(newMap)
        return newMap, true   // ? this wasn't in the original code
    }

    // we must delete our own node
    if self.isLeaf() {  // we have no children
        return nilMap, true
    }
    /*
    if self.subtreeCount() == 1 { // only one subtree
        for _, t := range self.children {
            if t != nilMap {
                return t, true
            }
        }
        panic("Tree with 1 subtree actually had no subtrees")
    }
    */

    // find a node to replace us
    i := -1
    size := -1
    for j, t := range self.children {
        if t.Size() > size {
            i = j
            size = t.Size()
        }
    }

    // make chosen leaf smaller
    replacement, child := self.children[i].deleteLeftmost()
    newMap := replacement.clone()
    for j := range self.children {
        if j == i {
            newMap.children[j] = child
        } else {
            newMap.children[j] = self.children[j]
        }
    }
    recalculateCount(newMap)
    return newMap, true
}

// delete the leftmost node in a tree returning the node that
// was deleted and the tree left over after its deletion
func (m *tree) deleteLeftmost() (*tree, *tree) {
    if m.isLeaf() {
        return m, nilMap
    }

    for i, t := range m.children {
        if t != nilMap {
            deleted, child := t.deleteLeftmost()
            newMap := m.clone()
            newMap.children[i] = child
            recalculateCount(newMap)
            return deleted, newMap
        }
    }
    panic("Tree isn't a leaf but also had no children. How does that happen?")
}

// isLeaf returns true if this is a leaf node
func (m *tree) isLeaf() bool {
    return m.Size() == 1
}

// returns the number of child subtrees we have
func (m *tree) subtreeCount() int {
    count := 0
    for _, t := range m.children {
        if t != nilMap {
            count++
        }
    }
    return count
}

func (m *tree) Lookup(key string) (Any, bool) {
    hash := hashKey(key)
    return lookupLowLevel(m, hash, hash)
}

func lookupLowLevel(self *tree, partialHash, hash uint64) (Any, bool) {
    if self.IsNil() { // an empty tree is easy
        return nil, false
    }

    if hash != self.hash {
        i := partialHash % childCount
        return lookupLowLevel(self.children[i], partialHash>>shiftSize, hash)
    }

    // we found it
    return self.value, true
}

func (m *tree) Size() int {
    return m.count
}

func (m *tree) ForEach(f func(key string, val Any)) {
    if m.IsNil() {
        return
    }

    // ourself
    f(m.key, m.value)

    // children
    for _, t := range m.children {
        if t != nilMap {
            t.ForEach(f)
        }
    }
}

func (m *tree) Keys() []string {
    keys := make([]string, m.Size())
    i := 0
    m.ForEach( func (k string, v Any) {
        keys[i] = k
        i++
    })
    return keys
}

// make it easier to display maps for debugging
func (m *tree) String() string {
    keys := m.Keys()
    buf := bytes.NewBufferString("{")
    for _, key := range keys {
        val, _ := m.Lookup(key)
        Fprintf(buf, "%s: %s, ", key, val)
    }
    Fprintf(buf, "}\n")
    return buf.String()
}
<|endoftext|>