<commit_before>// Package pgx is a PostgreSQL database driver.
/*
pgx provides lower level access to PostgreSQL than the standard database/sql
It remains as similar to the database/sql interface as possible while
providing better speed and access to PostgreSQL specific features. Import
github.com/jack/pgx/stdlib to use pgx as a database/sql compatible driver.

Query Interface

pgx implements Query and Scan in the familiar database/sql style.

    var sum int32

    // Send the query to the server. The returned rows MUST be closed
    // before conn can be used again.
    rows, err := conn.Query("select generate_series(1,$1)", 10)
    if err != nil {
        return err
    }

    // rows.Close is called by rows.Next when all rows are read
    // or an error occurs in Next or Scan. So it may optionally be
    // omitted if nothing in the rows.Next loop can panic. It is
    // safe to close rows multiple times.
    defer rows.Close()

    // Iterate through the result set
    for rows.Next() {
        var n int32
        err = rows.Scan(&n)
        if err != nil {
            return err
        }
        sum += n
    }

    // Any errors encountered by rows.Next or rows.Scan will be returned here
    if rows.Err() != nil {
        return err
    }

    // No errors found - do something with sum

pgx also implements QueryRow in the same style as database/sql.

    var name string
    var weight int64
    err := conn.QueryRow("select name, weight from widgets where id=$1", 42).Scan(&name, &weight)
    if err != nil {
        return err
    }

Use Exec to execute a query that does not return a result set.

    commandTag, err := conn.Exec("delete from widgets where id=$1", 42)
    if err != nil {
        return err
    }
    if commandTag.RowsAffected() != 1 {
        return errors.New("No row found to delete")
    }

Connection Pool

Connection pool usage is explicit and configurable. In pgx, a connection can
be created and managed directly, or a connection pool with a configurable
maximum connections can be used. Also, the connection pool offers an after
connect hook that allows every connection to be automatically setup before
being made available in the connection pool. This is especially useful to
ensure all connections have the same prepared statements available or to
change any other connection settings.

It delegates Query, QueryRow, Exec, and Begin functions to an automatically
checked out and released connection so you can avoid manually acquiring and
releasing connections when you do not need that level of control.

    var name string
    var weight int64
    err := pool.QueryRow("select name, weight from widgets where id=$1", 42).Scan(&name, &weight)
    if err != nil {
        return err
    }

Base Type Mapping

pgx maps between all common base types directly between Go and PostgreSQL. In
particular:

    Go           PostgreSQL
    -----------------------
    string       varchar
                 text

    // Integers are automatically be converted to any other integer type if
    // it can be done without overflow or underflow.
    int8
    int16        smallint
    int32        int
    int64        bigint
    int
    uint8
    uint16
    uint32
    uint64
    uint

    // Floats are strict and do not automatically convert like integers.
    float32      float4
    float64      float8

    time.Time   date
                timestamp
                timestamptz

    []byte      bytea

Null Mapping

pgx can map nulls in two ways. The first is Null* types that have a data field
and a valid field. They work in a similar fashion to database/sql. The second
is to use a pointer to a pointer.

    var foo pgx.NullString
    var bar *string
    err := conn.QueryRow("select foo, bar from widgets where id=$1", 42).Scan(&a, &b)
    if err != nil {
        return err
    }

Array Mapping

pgx maps between int16, int32, int64, float32, float64, and string Go slices
and the equivalent PostgreSQL array type. Go slices of native types do not
support nulls, so if a PostgreSQL array that contains a null is read into a
native Go slice an error will occur.

Hstore Mapping

pgx includes an Hstore type and a NullHstore type. Hstore is simply a
map[string]string and is preferred when the hstore contains no nulls. NullHstore
follows the Null* pattern and supports null values.

JSON and JSONB Mapping

pgx includes built-in support to marshal and unmarshal between Go types and
the PostgreSQL JSON and JSONB.

Inet and CIDR Mapping

pgx encodes from net.IPNet to and from inet and cidr PostgreSQL types. In
addition, as a convenience pgx will encode from a net.IP; it will assume a /32
netmask for IPv4 and a /128 for IPv6.

Custom Type Support

pgx includes support for the common data types like integers, floats, strings,
dates, and times that have direct mappings between Go and SQL. In addition,
pgx uses the github.com/jackc/pgx/pgtype library to support more types. See
documention for that library for instructions on how to implement custom
types.

See example_custom_type_test.go for an example of a custom type for the
PostgreSQL point type.

pgx also includes support for custom types implementing the database/sql.Scanner
and database/sql/driver.Valuer interfaces.

Raw Bytes Mapping

[]byte passed as arguments to Query, QueryRow, and Exec are passed unmodified
to PostgreSQL.

Transactions

Transactions are started by calling Begin or BeginEx. The BeginEx variant
can create a transaction with a specified isolation level.

    tx, err := conn.Begin()
    if err != nil {
        return err
    }
    // Rollback is safe to call even if the tx is already closed, so if
    // the tx commits successfully, this is a no-op
    defer tx.Rollback()

    _, err = tx.Exec("insert into foo(id) values (1)")
    if err != nil {
        return err
    }

    err = tx.Commit()
    if err != nil {
        return err
    }

Copy Protocol

Use CopyTo to efficiently insert multiple rows at a time using the PostgreSQL
copy protocol. CopyTo accepts a CopyToSource interface. If the data is already
in a [][]interface{} use CopyToRows to wrap it in a CopyToSource interface. Or
implement CopyToSource to avoid buffering the entire data set in memory.

    rows := [][]interface{}{
        {"John", "Smith", int32(36)},
        {"Jane", "Doe", int32(29)},
    }

    copyCount, err := conn.CopyTo(
        "people",
        []string{"first_name", "last_name", "age"},
        pgx.CopyToRows(rows),
    )

CopyTo can be faster than an insert with as few as 5 rows.

Listen and Notify

pgx can listen to the PostgreSQL notification system with the
WaitForNotification function. It takes a maximum time to wait for a
notification.

    err := conn.Listen("channelname")
    if err != nil {
        return nil
    }

    if notification, err := conn.WaitForNotification(time.Second); err != nil {
        // do something with notification
    }

TLS

The pgx ConnConfig struct has a TLSConfig field. If this field is
nil, then TLS will be disabled. If it is present, then it will be used to
configure the TLS connection. This allows total configuration of the TLS
connection.

Logging

pgx defines a simple logger interface. Connections optionally accept a logger
that satisfies this interface. Set LogLevel to control logging verbosity.
Adapters for github.com/inconshreveable/log15, github.com/Sirupsen/logrus, and
the testing log are provided in the log directory.
*/
package pgx
<commit_msg>Add missing `pgx.Identifier` to `CopyFrom` example<commit_after>// Package pgx is a PostgreSQL database driver.
/*
pgx provides lower level access to PostgreSQL than the standard database/sql
It remains as similar to the database/sql interface as possible while
providing better speed and access to PostgreSQL specific features. Import
github.com/jack/pgx/stdlib to use pgx as a database/sql compatible driver.

Query Interface

pgx implements Query and Scan in the familiar database/sql style.

    var sum int32

    // Send the query to the server. The returned rows MUST be closed
    // before conn can be used again.
    rows, err := conn.Query("select generate_series(1,$1)", 10)
    if err != nil {
        return err
    }

    // rows.Close is called by rows.Next when all rows are read
    // or an error occurs in Next or Scan. So it may optionally be
    // omitted if nothing in the rows.Next loop can panic. It is
    // safe to close rows multiple times.
    defer rows.Close()

    // Iterate through the result set
    for rows.Next() {
        var n int32
        err = rows.Scan(&n)
        if err != nil {
            return err
        }
        sum += n
    }

    // Any errors encountered by rows.Next or rows.Scan will be returned here
    if rows.Err() != nil {
        return err
    }

    // No errors found - do something with sum

pgx also implements QueryRow in the same style as database/sql.

    var name string
    var weight int64
    err := conn.QueryRow("select name, weight from widgets where id=$1", 42).Scan(&name, &weight)
    if err != nil {
        return err
    }

Use Exec to execute a query that does not return a result set.

    commandTag, err := conn.Exec("delete from widgets where id=$1", 42)
    if err != nil {
        return err
    }
    if commandTag.RowsAffected() != 1 {
        return errors.New("No row found to delete")
    }

Connection Pool

Connection pool usage is explicit and configurable. In pgx, a connection can
be created and managed directly, or a connection pool with a configurable
maximum connections can be used. Also, the connection pool offers an after
connect hook that allows every connection to be automatically setup before
being made available in the connection pool. This is especially useful to
ensure all connections have the same prepared statements available or to
change any other connection settings.

It delegates Query, QueryRow, Exec, and Begin functions to an automatically
checked out and released connection so you can avoid manually acquiring and
releasing connections when you do not need that level of control.

    var name string
    var weight int64
    err := pool.QueryRow("select name, weight from widgets where id=$1", 42).Scan(&name, &weight)
    if err != nil {
        return err
    }

Base Type Mapping

pgx maps between all common base types directly between Go and PostgreSQL. In
particular:

    Go           PostgreSQL
    -----------------------
    string       varchar
                 text

    // Integers are automatically be converted to any other integer type if
    // it can be done without overflow or underflow.
    int8
    int16        smallint
    int32        int
    int64        bigint
    int
    uint8
    uint16
    uint32
    uint64
    uint

    // Floats are strict and do not automatically convert like integers.
    float32      float4
    float64      float8

    time.Time   date
                timestamp
                timestamptz

    []byte      bytea

Null Mapping

pgx can map nulls in two ways. The first is Null* types that have a data field
and a valid field. They work in a similar fashion to database/sql. The second
is to use a pointer to a pointer.

    var foo pgx.NullString
    var bar *string
    err := conn.QueryRow("select foo, bar from widgets where id=$1", 42).Scan(&a, &b)
    if err != nil {
        return err
    }

Array Mapping

pgx maps between int16, int32, int64, float32, float64, and string Go slices
and the equivalent PostgreSQL array type. Go slices of native types do not
support nulls, so if a PostgreSQL array that contains a null is read into a
native Go slice an error will occur.

Hstore Mapping

pgx includes an Hstore type and a NullHstore type. Hstore is simply a
map[string]string and is preferred when the hstore contains no nulls. NullHstore
follows the Null* pattern and supports null values.

JSON and JSONB Mapping

pgx includes built-in support to marshal and unmarshal between Go types and
the PostgreSQL JSON and JSONB.

Inet and CIDR Mapping

pgx encodes from net.IPNet to and from inet and cidr PostgreSQL types. In
addition, as a convenience pgx will encode from a net.IP; it will assume a /32
netmask for IPv4 and a /128 for IPv6.

Custom Type Support

pgx includes support for the common data types like integers, floats, strings,
dates, and times that have direct mappings between Go and SQL. In addition,
pgx uses the github.com/jackc/pgx/pgtype library to support more types. See
documention for that library for instructions on how to implement custom
types.

See example_custom_type_test.go for an example of a custom type for the
PostgreSQL point type.

pgx also includes support for custom types implementing the database/sql.Scanner
and database/sql/driver.Valuer interfaces.

Raw Bytes Mapping

[]byte passed as arguments to Query, QueryRow, and Exec are passed unmodified
to PostgreSQL.

Transactions

Transactions are started by calling Begin or BeginEx. The BeginEx variant
can create a transaction with a specified isolation level.

    tx, err := conn.Begin()
    if err != nil {
        return err
    }
    // Rollback is safe to call even if the tx is already closed, so if
    // the tx commits successfully, this is a no-op
    defer tx.Rollback()

    _, err = tx.Exec("insert into foo(id) values (1)")
    if err != nil {
        return err
    }

    err = tx.Commit()
    if err != nil {
        return err
    }

Copy Protocol

Use CopyTo to efficiently insert multiple rows at a time using the PostgreSQL
copy protocol. CopyTo accepts a CopyToSource interface. If the data is already
in a [][]interface{} use CopyToRows to wrap it in a CopyToSource interface. Or
implement CopyToSource to avoid buffering the entire data set in memory.

    rows := [][]interface{}{
        {"John", "Smith", int32(36)},
        {"Jane", "Doe", int32(29)},
    }

    copyCount, err := conn.CopyFrom(
        pgx.Identifier{"people"},
        []string{"first_name", "last_name", "age"},
        pgx.CopyToRows(rows),
    )

CopyTo can be faster than an insert with as few as 5 rows.

Listen and Notify

pgx can listen to the PostgreSQL notification system with the
WaitForNotification function. It takes a maximum time to wait for a
notification.

    err := conn.Listen("channelname")
    if err != nil {
        return nil
    }

    if notification, err := conn.WaitForNotification(time.Second); err != nil {
        // do something with notification
    }

TLS

The pgx ConnConfig struct has a TLSConfig field. If this field is
nil, then TLS will be disabled. If it is present, then it will be used to
configure the TLS connection. This allows total configuration of the TLS
connection.

Logging

pgx defines a simple logger interface. Connections optionally accept a logger
that satisfies this interface. Set LogLevel to control logging verbosity.
Adapters for github.com/inconshreveable/log15, github.com/Sirupsen/logrus, and
the testing log are provided in the log directory.
*/
package pgx
<|endoftext|>


<commit_before>// Package dl implements dynamic of shared libraries, like
// dlopen() and dlsym() in C.
//
//
// This package supports the following type mapping between Go
// and C.
//
//  Go		    -   C
//  (u)int	    -   (unsigned) long
//  (u)int8	    -   uint8_t / int8_t
//  (u)int16	    -   uint16_t / int16_t
//  (u)int32	    -   (unsigned) int
//  (u)int64	    -   uint64_t / int64_t
//  float32	    -	float
//  float64	    -	double
//  string	    -   char * (read only)
//  []byte	    -   char * (readwrite)
//  slices	    -   pointer to first argument
//  uintptr	    -   void *
//  unsafe.Pointer  -	void *
//
// No struct types are supported at this time.
//
// Retrieving variable symbols
//
// Symbols pointing to variables might be retrieved
// either as values or pointers. Given a C library
// which declares a symbol as:
//
//  int my_int = 8;
//
// It might be retrieved as a value, returning a copy with:
//
//  var myInt int32
//  if err := lib.Sym("my_int", &myInt); err != nil {
//	handle_error...
//  }
//
// Alternatively, a pointer to the variable might be obtained as:
//
//  var myInt *int32
//  if err := lib.Sym("my_int", &myInt); err != nil {
//	handle_error...
//  }
//
// Note that changing the value via the pointer will change the symbol
// in the loaded library, while changing the value obtained without the
// pointer will not, since a copy is made at lookup time.
//
// Retrieving function symbols
//
// This package also supports dynamically loading functions from libraries. To
// do so you must declare a function variable which matches the signature of the
// C function. Note that type mismatches will likely result in crashes, so use this
// feature with extreme care. Argument and return types must be of one of the
// supported types. See the examples in this package for the complete code.
//
//  var printf func(string, ...interface{}) int32
//  if err := lib.Sym("printf", &printf); err != nil {
//	handle_error...
//  }
//  printf("this string uses C format: %d\n", 7)
//
// Functions retrieved from a symbol can be used as standard Go functions.
//
// Overhead
//
// Typically, calling functions via this package rather than using cgo directly
// takes around 500ns more per call, due to reflection overhead. Future versions
// muight adopt a JIT strategy which should make it as fast as cgo.
package dl
<commit_msg>Fix typo<commit_after>// Package dl implements dynamic of shared libraries, like
// dlopen() and dlsym() in C.
//
//
// This package supports the following type mapping between Go
// and C.
//
//  Go		    -   C
//  (u)int	    -   (unsigned) long
//  (u)int8	    -   uint8_t / int8_t
//  (u)int16	    -   uint16_t / int16_t
//  (u)int32	    -   (unsigned) int
//  (u)int64	    -   uint64_t / int64_t
//  float32	    -	float
//  float64	    -	double
//  string	    -   char * (read only)
//  []byte	    -   char * (readwrite)
//  slices	    -   pointer to first argument
//  uintptr	    -   void *
//  unsafe.Pointer  -	void *
//
// No struct types are supported at this time.
//
// Retrieving variable symbols
//
// Symbols pointing to variables might be retrieved
// either as values or pointers. Given a C library
// which declares a symbol as:
//
//  int my_int = 8;
//
// It might be retrieved as a value, returning a copy with:
//
//  var myInt int32
//  if err := lib.Sym("my_int", &myInt); err != nil {
//	handle_error...
//  }
//
// Alternatively, a pointer to the variable might be obtained as:
//
//  var myInt *int32
//  if err := lib.Sym("my_int", &myInt); err != nil {
//	handle_error...
//  }
//
// Note that changing the value via the pointer will change the symbol
// in the loaded library, while changing the value obtained without the
// pointer will not, since a copy is made at lookup time.
//
// Retrieving function symbols
//
// This package also supports dynamically loading functions from libraries. To
// do so you must declare a function variable which matches the signature of the
// C function. Note that type mismatches will likely result in crashes, so use this
// feature with extreme care. Argument and return types must be of one of the
// supported types. See the examples in this package for the complete code.
//
//  var printf func(string, ...interface{}) int32
//  if err := lib.Sym("printf", &printf); err != nil {
//	handle_error...
//  }
//  printf("this string uses C format: %d\n", 7)
//
// Functions retrieved from a symbol can be used as standard Go functions.
//
// Overhead
//
// Typically, calling functions via this package rather than using cgo directly
// takes around 500ns more per call, due to reflection overhead. Future versions
// might adopt a JIT strategy which should make it as fast as cgo.
package dl
<|endoftext|>


<commit_before>// Copyright (c) 2014 AKUALAB INC., All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
Package dsp provides processors that can be chained together to build
digital signal processing systems.

Digital signals are represented as sequence of numbers where each number
is associated with a disctrete time. Discrete time is represented as a
squence of integers that can correspond to physycal time sampled at fixed
time intervals.

All operations are synchronous because all values must correspond to a discrete
time. For example, given and operation such as x[n] = f[n-1] + g[n-2], the
value x[4] is calculated using delayed values f[3] and g[2].

Processors are chained together using channels. Processors send data of
type Value which is a synonim of []float64. In mathematical terms, all inputs
and outputs are vectors. The dimension of the vectors is set by the processors
using configuration parameters, teh dimension of the input vestors, or by any
other method.

Data is pushed from a source and results can be read from any processor
in the chain.

Procesors have zero or more outputs and zero or more inputs.

A processor with multiple outputs sends the send value to other processors.

A processor with multiple inputs receive values from other processors. The inputs
can be interchangeable (they all have the same behavior) or not internchangeable.

Processors are connected using buffered channels of type (chan Value). A full channel
will block incoming values. If the application graph is not properly built or the
output values are not read, the application will eventually deadlock.

While the operations are synchronous the underlying computation is asynchronous.
Processors will consume input data and write outputs as long as they are not blocked.
This approach makes it possible to do parallel processing in hosts with multiple
CPUs. Processor must be go routine safe.

The following example implements a simple pipeline where the output of a processor
is the single input to the next processor:

	app := NewApp("A simple pipeline.", 1000)

	out := app.Run(
        dsp.Source(64, 2).Use(NewSquare(1, 0, 4, 4)),
        dsp.Window(64).Use(Hamming),
        dsp.WriteValues(os.Stdout, true),
	)

The processed vectors can be read from the "out" channel. In linear apps, all
the wiring between processors is hidden.

A pipeline can easily be converted into a single composite processor:

	newProc := app.Sequence(
        dsp.Source(64, 2).Use(NewSquare(1, 0, 4, 4)),
        dsp.Window(64).Use(Hamming),
        dsp.WriteValues(os.Stdout, true),
	)

A more realistic application will have processors with multiple
inputs and multiple outputs. The Builder functions provide a set of
tools to create the application graph.

For a comrehensive example see examples/speech2/main.go.

Convention: Input values should be treated as read-only because
they may be shared with other processors.
To quickly create a copy, do newValue = inputValue.Copy().

CREDITS:

I adapted the design from https://github.com/ghemawat/stream by Sanjay Ghemawat.
Package stream is designed to process streams of text by chaining filters.

CONTACT:

Leo Neumeyer
leo@akualab.com

*/
package dsp

import (
	"fmt"
	"sync"
)

type Value []float64

// Creates a copy of the value.
// Input values should be treated as read-only because
// they may be shared with other processors.
func (v Value) Copy() Value {
	vcopy := make(Value, len(v), len(v))
	copy(vcopy, v)
	return vcopy
}

type ToChan chan<- Value   // can only send to the channel
type FromChan <-chan Value // can only receive from the channel

// Processors must implement this interface.
type Processor interface {
	RunProc(in In, out Out) error
}

// Input to processor.
type In struct {
	From []FromChan // []<-chan Value
}

// Output from processor.
type Out struct {
	To []ToChan // chan<- Value
}

// Returns a pair of initialized In and Out objects.
func NewIO() (In, Out) {
	return In{From: []FromChan{}}, Out{To: []ToChan{}}
}

// Adds an output channel to processor.
func (out *Out) Add(ch ToChan) {
	out.To = append(out.To, ch)
}

// Adds an input channel to processor.
func (in *In) Add(ch FromChan) {
	in.From = append(in.From, ch)
}

// Get input channel for index.
func (in *In) Get(idx int) (FromChan, error) {
	if idx < len(in.From) {
		return in.From[idx], nil

	}
	return nil, fmt.Errorf("there is no input with index [%d]", idx)
}

// ProcFunc is an adapter type that allows the use of ordinary
// functions as Processors.  If f is a function with the appropriate
// signature, FilterFunc(f) is a Processor that calls f.
type ProcFunc func(In, Out) error

// RunProc calls this function. It implements the Processor interface.
func (f ProcFunc) RunProc(in In, out Out) error { return f(in, out) }

func runProc(p Processor, in In, out Out, e *procErrors) {
	e.record(p.RunProc(in, out))
	CloseOutputs(out)
}

// Sequence is a helper method that returns a processor that is the
// concatenation of all processor arguments.
// The output of a processor is fed as input to the next processor.
func (app *App) Sequence(procs ...Processor) Processor {
	if len(procs) == 1 {
		return procs[0]
	}
	return ProcFunc(func(in In, out Out) error {
		input := in.From[0]
		for _, p := range procs {
			c := app.Wire()
			app.ConnectOne(p, c, input)
			input = c
		}
		for v := range input {
			SendValue(v, out)
		}
		return app.Error()
	})
}

// Run executes a sequence of processors.
// It returns either nil, an error if any processor reported an error.
func (app *App) Run(procs ...Processor) FromChan {
	p := app.Sequence(procs...)
	in := app.Wire()
	close(in)
	out := app.Wire()
	app.ConnectOne(p, out, in)

	return out
}

// A DSP application.
type App struct {
	// App name.
	Name string
	// Default buffer size for connection channels.
	BufferSize int
	e          *procErrors
}

// Returns a new app.
func NewApp(name string, bufferSize int) *App {

	return &App{Name: name,
		e:          &procErrors{},
		BufferSize: bufferSize,
	}
}

// Connects multiple inputs and outputs to a processor.
func (app *App) Connect(p Processor, in In, out Out) {
	go runProc(p, in, out, app.e)
}

// Connects multiple inputs and one output to a processor.
func (app *App) ConnectOne(p Processor, out ToChan, ins ...FromChan) {
	//go runProc(p, PIO{Out: []ToChan{out}, In: ins}, app.e)
	go runProc(p, In{From: ins}, Out{To: []ToChan{out}}, app.e)
}

// Returns error if any.
func (app *App) Error() error {
	return app.e.getError()
}

// Creates a channel for wiring processors.
func (app *App) Wire() chan Value {
	return make(chan Value, app.BufferSize)
}

// Closes all the output channels.
func CloseOutputs(out Out) {
	for _, o := range out.To {
		close(o)
	}
}

// Sends a value to all the output channels.
func SendValue(v Value, out Out) {

	for _, o := range out.To {
		o <- v
	}
}

// procErrors records errors accumulated during the execution of a processor.
type procErrors struct {
	mu  sync.Mutex
	err error
}

func (e *procErrors) record(err error) {
	if err != nil {
		e.mu.Lock()
		if e.err == nil {
			e.err = err
		}
		e.mu.Unlock()
	}
}

func (e *procErrors) getError() error {
	e.mu.Lock()
	defer e.mu.Unlock()
	return e.err
}
<commit_msg>Edit documentation.<commit_after>// Copyright (c) 2014 AKUALAB INC., All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
Package dsp provides processors that can be chained together to build
digital signal processing systems.

Digital signals are represented as sequence of numbers where each number
is associated with a disctrete time. Discrete time is represented as a
squence of integers that can correspond to physycal time sampled at fixed
time intervals.

All operations are synchronous because all values must correspond to a discrete
time. For example, given and operation such as x[n] = f[n-1] + g[n-2], the
value x[4] is calculated using delayed values f[3] and g[2].

Processors are chained together using channels. Processors send data of
type Value which is a synonim of []float64. In mathematical terms, all inputs
and outputs are vectors. The dimension of the vectors is set by the processors
using configuration parameters, teh dimension of the input vestors, or by any
other method.

Data is pushed from a source and results can be read from any processor
in the chain.

Procesors have zero or more outputs and zero or more inputs.

A processor with multiple outputs sends the send value to other processors.

A processor with multiple inputs receive values from other processors. The inputs
can be interchangeable (they all have the same behavior) or not internchangeable.

Processors are connected using buffered channels of type (chan Value). A full channel
will block incoming values. If the application graph is not properly built or the
output values are not read, the application will eventually deadlock.

While the operations are synchronous the underlying computation is asynchronous.
Processors will consume input data and write outputs as long as they are not blocked.
This approach makes it possible to do parallel processing in hosts with multiple
CPUs. Processor must be go routine safe.

The following example implements a simple pipeline where the output of a processor
is the single input to the next processor:

	app := NewApp("A simple pipeline.", 1000)

	out := app.Run(
        dsp.Source(64, 2).Use(NewSquare(1, 0, 4, 4)),
        dsp.Window(64).Use(Hamming),
        dsp.WriteValues(os.Stdout, true),
	)

The processed vectors can be read from the "out" channel. In linear apps, all
the wiring between processors is hidden.

A pipeline can easily be converted into a single composite processor:

	newProc := app.Sequence(
        dsp.Source(64, 2).Use(NewSquare(1, 0, 4, 4)),
        dsp.Window(64).Use(Hamming),
        dsp.WriteValues(os.Stdout, true),
	)

A more realistic application will have processors with multiple
inputs and multiple outputs. The Builder functions provide a set of
tools to create the application graph.

For a comrehensive example see examples/speech2/main.go.

Convention: Input values should be treated as read-only because
they may be shared with other processors.
To quickly create a copy, do newValue = inputValue.Copy().

CREDITS:

I adapted the design from https://github.com/ghemawat/stream by Sanjay Ghemawat.
Package stream is designed to process streams of text by chaining filters. Package stream
was itself adapted from Gustavo Niemeyer's "pipe" https://gopkg.in/pipe.v2 . These are two
interesting designs for piping data throuch channels. Check them out.

CONTACT:

Leo Neumeyer
leo@akualab.com

*/
package dsp

import (
	"fmt"
	"sync"
)

type Value []float64

// Creates a copy of the value.
// Input values should be treated as read-only because
// they may be shared with other processors.
func (v Value) Copy() Value {
	vcopy := make(Value, len(v), len(v))
	copy(vcopy, v)
	return vcopy
}

type ToChan chan<- Value   // can only send to the channel
type FromChan <-chan Value // can only receive from the channel

// Processors must implement this interface.
type Processor interface {
	RunProc(in In, out Out) error
}

// Input to processor.
type In struct {
	From []FromChan // []<-chan Value
}

// Output from processor.
type Out struct {
	To []ToChan // chan<- Value
}

// Returns a pair of initialized In and Out objects.
func NewIO() (In, Out) {
	return In{From: []FromChan{}}, Out{To: []ToChan{}}
}

// Adds an output channel to processor.
func (out *Out) Add(ch ToChan) {
	out.To = append(out.To, ch)
}

// Adds an input channel to processor.
func (in *In) Add(ch FromChan) {
	in.From = append(in.From, ch)
}

// Get input channel for index.
func (in *In) Get(idx int) (FromChan, error) {
	if idx < len(in.From) {
		return in.From[idx], nil

	}
	return nil, fmt.Errorf("there is no input with index [%d]", idx)
}

// ProcFunc is an adapter type that allows the use of ordinary
// functions as Processors.  If f is a function with the appropriate
// signature, FilterFunc(f) is a Processor that calls f.
type ProcFunc func(In, Out) error

// RunProc calls this function. It implements the Processor interface.
func (f ProcFunc) RunProc(in In, out Out) error { return f(in, out) }

func runProc(p Processor, in In, out Out, e *procErrors) {
	e.record(p.RunProc(in, out))
	CloseOutputs(out)
}

// Sequence is a helper method that returns a processor that is the
// concatenation of all processor arguments.
// The output of a processor is fed as input to the next processor.
func (app *App) Sequence(procs ...Processor) Processor {
	if len(procs) == 1 {
		return procs[0]
	}
	return ProcFunc(func(in In, out Out) error {
		input := in.From[0]
		for _, p := range procs {
			c := app.Wire()
			app.ConnectOne(p, c, input)
			input = c
		}
		for v := range input {
			SendValue(v, out)
		}
		return app.Error()
	})
}

// Run executes a sequence of processors.
// It returns either nil, an error if any processor reported an error.
func (app *App) Run(procs ...Processor) FromChan {
	p := app.Sequence(procs...)
	in := app.Wire()
	close(in)
	out := app.Wire()
	app.ConnectOne(p, out, in)

	return out
}

// A DSP application.
type App struct {
	// App name.
	Name string
	// Default buffer size for connection channels.
	BufferSize int
	e          *procErrors
}

// Returns a new app.
func NewApp(name string, bufferSize int) *App {

	return &App{Name: name,
		e:          &procErrors{},
		BufferSize: bufferSize,
	}
}

// Connects multiple inputs and outputs to a processor.
func (app *App) Connect(p Processor, in In, out Out) {
	go runProc(p, in, out, app.e)
}

// Connects multiple inputs and one output to a processor.
func (app *App) ConnectOne(p Processor, out ToChan, ins ...FromChan) {
	//go runProc(p, PIO{Out: []ToChan{out}, In: ins}, app.e)
	go runProc(p, In{From: ins}, Out{To: []ToChan{out}}, app.e)
}

// Returns error if any.
func (app *App) Error() error {
	return app.e.getError()
}

// Creates a channel for wiring processors.
func (app *App) Wire() chan Value {
	return make(chan Value, app.BufferSize)
}

// Closes all the output channels.
func CloseOutputs(out Out) {
	for _, o := range out.To {
		close(o)
	}
}

// Sends a value to all the output channels.
func SendValue(v Value, out Out) {

	for _, o := range out.To {
		o <- v
	}
}

// procErrors records errors accumulated during the execution of a processor.
type procErrors struct {
	mu  sync.Mutex
	err error
}

func (e *procErrors) record(err error) {
	if err != nil {
		e.mu.Lock()
		if e.err == nil {
			e.err = err
		}
		e.mu.Unlock()
	}
}

func (e *procErrors) getError() error {
	e.mu.Lock()
	defer e.mu.Unlock()
	return e.err
}
<|endoftext|>


<commit_before>package multiconfig

import (
	"fmt"
	"os"
	"reflect"
	"strings"

	"github.com/fatih/camelcase"
	"github.com/fatih/structs"
)

// EnvironmentLoader satisifies the loader interface. It loads the
// configuration from the environment variables in the form of
// STRUCTNAME_FIELDNAME.
type EnvironmentLoader struct {
	// Prefix prepends given string to every environment variable
	// {STRUCTNAME}_FIELDNAME will be {PREFIX}_FIELDNAME
	Prefix string

	// CamelCase adds a seperator for field names in camelcase form. A
	// fieldname of "AccessKey" would generate a environment name of
	// "STRUCTNAME_ACCESSKEY". If CamelCase is enabled, the environment name
	// will be generated in the form of "STRUCTNAME_ACCESS_KEY"
	CamelCase bool
}

func (e *EnvironmentLoader) getPrefix(s *structs.Struct) string {
	if e.Prefix != "" {
		return e.Prefix
	}

	return s.Name()
}

// Load loads the source into the config defined by struct s
func (e *EnvironmentLoader) Load(s interface{}) error {
	strct := structs.New(s)

	prefix := e.getPrefix(strct)

	for _, field := range strct.Fields() {
		if err := e.processField(prefix, field); err != nil {
			return err
		}
	}

	return nil
}

// processField gets leading name for the env variable and combines the current
// field's name and generates environemnt variable names recursively
func (e *EnvironmentLoader) processField(prefix string, field *structs.Field) error {
	fieldName := e.generateFieldName(prefix, field)

	switch field.Kind() {
	case reflect.Struct:
		for _, f := range field.Fields() {
			if err := e.processField(fieldName, f); err != nil {
				return err
			}
		}
	default:
		v := os.Getenv(fieldName)
		if v == "" {
			return nil
		}

		if err := fieldSet(field, v); err != nil {
			return err
		}
	}

	return nil
}

// PrintEnvs prints the generated environment variables to the std out.
func (e *EnvironmentLoader) PrintEnvs(s interface{}) {
	strct := structs.New(s)

	prefix := e.getPrefix(strct)

	for _, field := range strct.Fields() {
		e.printField(prefix, field)
	}
}

// printField prints the field of the config struct for the flag.Usage
func (e *EnvironmentLoader) printField(prefix string, field *structs.Field) {
	fieldName := e.generateFieldName(prefix, field)

	switch field.Kind() {
	case reflect.Struct:
		for _, f := range field.Fields() {
			e.printField(fieldName, f)
		}
	default:
		fmt.Println("  ", fieldName)
	}
}

// generateFieldName generates the fiels name combined with the prefix and the
// struct's field name
func (e *EnvironmentLoader) generateFieldName(prefix string, field *structs.Field) string {
	fieldName := strings.ToUpper(field.Name())
	if e.CamelCase {
		fieldName = strings.ToUpper(strings.Join(camelcase.Split(field.Name()), "_"))
	}

	return strings.ToUpper(prefix) + "_" + fieldName
}
<commit_msg>fix typo<commit_after>package multiconfig

import (
	"fmt"
	"os"
	"reflect"
	"strings"

	"github.com/fatih/camelcase"
	"github.com/fatih/structs"
)

// EnvironmentLoader satisifies the loader interface. It loads the
// configuration from the environment variables in the form of
// STRUCTNAME_FIELDNAME.
type EnvironmentLoader struct {
	// Prefix prepends given string to every environment variable
	// {STRUCTNAME}_FIELDNAME will be {PREFIX}_FIELDNAME
	Prefix string

	// CamelCase adds a seperator for field names in camelcase form. A
	// fieldname of "AccessKey" would generate a environment name of
	// "STRUCTNAME_ACCESSKEY". If CamelCase is enabled, the environment name
	// will be generated in the form of "STRUCTNAME_ACCESS_KEY"
	CamelCase bool
}

func (e *EnvironmentLoader) getPrefix(s *structs.Struct) string {
	if e.Prefix != "" {
		return e.Prefix
	}

	return s.Name()
}

// Load loads the source into the config defined by struct s
func (e *EnvironmentLoader) Load(s interface{}) error {
	strct := structs.New(s)

	prefix := e.getPrefix(strct)

	for _, field := range strct.Fields() {
		if err := e.processField(prefix, field); err != nil {
			return err
		}
	}

	return nil
}

// processField gets leading name for the env variable and combines the current
// field's name and generates environemnt variable names recursively
func (e *EnvironmentLoader) processField(prefix string, field *structs.Field) error {
	fieldName := e.generateFieldName(prefix, field)

	switch field.Kind() {
	case reflect.Struct:
		for _, f := range field.Fields() {
			if err := e.processField(fieldName, f); err != nil {
				return err
			}
		}
	default:
		v := os.Getenv(fieldName)
		if v == "" {
			return nil
		}

		if err := fieldSet(field, v); err != nil {
			return err
		}
	}

	return nil
}

// PrintEnvs prints the generated environment variables to the std out.
func (e *EnvironmentLoader) PrintEnvs(s interface{}) {
	strct := structs.New(s)

	prefix := e.getPrefix(strct)

	for _, field := range strct.Fields() {
		e.printField(prefix, field)
	}
}

// printField prints the field of the config struct for the flag.Usage
func (e *EnvironmentLoader) printField(prefix string, field *structs.Field) {
	fieldName := e.generateFieldName(prefix, field)

	switch field.Kind() {
	case reflect.Struct:
		for _, f := range field.Fields() {
			e.printField(fieldName, f)
		}
	default:
		fmt.Println("  ", fieldName)
	}
}

// generateFieldName generates the field name combined with the prefix and the
// struct's field name
func (e *EnvironmentLoader) generateFieldName(prefix string, field *structs.Field) string {
	fieldName := strings.ToUpper(field.Name())
	if e.CamelCase {
		fieldName = strings.ToUpper(strings.Join(camelcase.Split(field.Name()), "_"))
	}

	return strings.ToUpper(prefix) + "_" + fieldName
}
<|endoftext|>


<commit_before>/********************************
*** Web server API for Go     ***
*** Code is under MIT license ***
*** Code by CodingFerret      ***
*** github.com/squiidz        ***
*********************************/

package fur

import (
	"fmt"
	"log"
	"net/http"
)

var (
	origin Origin
)

// Simple Server structure for a web server.
type Server struct {
	Host   string
	Port   string
	Log    bool
	mux    *http.ServeMux
	routes []*Route
}

type MiddleWare func(http.Handler) http.Handler

type Origin []MiddleWare

// Create a NewServer instance with the given value.
// Host: "localhost"
// Port: ":8080"
// Log: true/false
// Options: functions to run on the server instance who's gonna be return.
func NewServer(host string, port string, log bool, options ...func(s *Server)) *Server {
	svr := Server{host, port, log, http.NewServeMux(), []*Route{}}
	if options != nil {
		for _, option := range options {
			option(&svr)
		}
	}
	return &svr
}

// Add Global Middleware to origin
func (s *Server) Stack(middles ...MiddleWare) {
	for _, middle := range middles {
		origin = append(origin, middle)
	}
}

// Start Listening on host and port of the Server.
// Log the request if the log was initiated as true in NewServer.
func (s *Server) Start() {
	fmt.Printf("[+] Server Running on %s ... \n", s.Port)
	if s.routes != nil {
		for _, r := range s.routes {
			s.mux.Handle(r.Path, r)
		}
	}
	if s.Log {
		http.ListenAndServe(s.Host+s.Port, s.logger(s.mux))
	}
	http.ListenAndServe(s.Host+s.Port, s.mux)
}

// Add function with the right sigature to the Server Mux
// and chain the provided middlewares on it.
func (s *Server) AddRoute(path string, f func(rw http.ResponseWriter, req *http.Request), middles ...MiddleWare) *Route {
	var stack http.Handler
	var midStack = origin

	if middles != nil || midStack != nil {
		for _, mid := range middles {
			midStack = append(midStack, mid)
		}
		stack = midStack[0](http.HandlerFunc(f))
		stack = wrap(stack, midStack[1:])
	} else {
		stack = http.HandlerFunc(f)
	}

	r := NewRoute(path, stack, "")
	s.routes = append(s.routes, r)
	return r
}

// Temporary way for serving static files
func (s *Server) AddStatic(path string, dir string) {
	s.mux.Handle(path, http.StripPrefix(path, http.FileServer(http.Dir(dir))))
}

// Log request to the Server.
func (s *Server) logger(mux http.Handler) http.Handler {
	return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
		log.Printf("%s %s %s", req.RemoteAddr, req.Method, req.URL)
		mux.ServeHTTP(rw, req)
	})
}

// Only Wrap the middleware on the provided http.Handler
func wrap(stack http.Handler, middles []MiddleWare) http.Handler {
	for i := len(middles) - 1; i >= 0; i-- {
		stack = middles[i](stack)
	}

	return stack
}
<commit_msg>Minor changes<commit_after>/********************************
*** Web server API for Go     ***
*** Code is under MIT license ***
*** Code by CodingFerret      ***
*** github.com/squiidz        ***
*********************************/

package fur

import (
	"fmt"
	"log"
	"net/http"
)

var (
	origin Origin
)

// Simple Server structure for a web server.
type Server struct {
	Host   string
	Port   string
	Log    bool
	mux    *http.ServeMux
	routes []*Route
}

type MiddleWare func(http.Handler) http.Handler

type Origin []MiddleWare

// Create a NewServer instance with the given value.
// Host: "localhost"
// Port: ":8080"
// Log: true/false
// Options: functions to run on the server instance who's gonna be return.
func NewServer(host string, port string, log bool, options ...func(s *Server)) *Server {
	svr := Server{host, port, log, http.NewServeMux(), []*Route{}}
	if options != nil {
		for _, option := range options {
			option(&svr)
		}
	}
	return &svr
}

// Add Global Middleware to origin
func (s *Server) Stack(middles ...MiddleWare) {
	for _, middle := range middles {
		origin = append(origin, middle)
	}
}

// Start Listening on host and port of the Server.
// Log the request if the log was initiated as true in NewServer.
func (s *Server) Start() {
	fmt.Printf("[+] Server listening on: %s\n", s.Port[1:])
	if s.routes != nil {
		for _, r := range s.routes {
			s.mux.Handle(r.Path, r)
		}
	}
	if s.Log {
		http.ListenAndServe(s.Host+s.Port, s.logger(s.mux))
	}
	http.ListenAndServe(s.Host+s.Port, s.mux)
}

// Add function with the right sigature to the Server Mux
// and chain the provided middlewares on it.
func (s *Server) AddRoute(path string, f func(rw http.ResponseWriter, req *http.Request), middles ...MiddleWare) *Route {
	var stack http.Handler
	var midStack = origin

	if middles != nil || midStack != nil {
		for _, mid := range middles {
			midStack = append(midStack, mid)
		}
		stack = midStack[0](http.HandlerFunc(f))
		stack = wrap(stack, midStack[1:])
	} else {
		stack = http.HandlerFunc(f)
	}

	r := NewRoute(path, stack, "")
	s.routes = append(s.routes, r)
	return r
}

// Temporary way for serving static files
func (s *Server) AddStatic(path string, dir string) {
	s.mux.Handle(path, http.StripPrefix(path, http.FileServer(http.Dir(dir))))
}

func (s *Server) NotFound(f func(rw http.ResponseWriter, req *http.Request)) http.Handler {
	return http.HandlerFunc(f)
}

// Log request to the Server.
func (s *Server) logger(mux http.Handler) http.Handler {
	return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
		log.Printf("%s %s %s", req.RemoteAddr, req.Method, req.URL)
		mux.ServeHTTP(rw, req)
	})
}

// Only Wrap the middleware on the provided http.Handler
func wrap(stack http.Handler, middles []MiddleWare) http.Handler {
	for i := len(middles) - 1; i >= 0; i-- {
		stack = middles[i](stack)
	}

	return stack
}
<|endoftext|>


<commit_before>package main

import (
	"io/ioutil"
	"path/filepath"
	"sort"
)

func GetProjects(datapath string) ([]string, error) {
	dir, err := ioutil.ReadDir(datapath)
	if err != nil {
		return []string{}, err
	}

	var out []string
	for _, d := range dir {
		file := d.Name()
		ext := filepath.Ext(file)
		name := file[0 : len(file)-len(ext)]

		out = append(out, name)
	}

	sort.Strings(out)
	return out, nil
}
<commit_msg>will not print dotfiles as projects anymore.<commit_after>package main

import (
	"io/ioutil"
	"path/filepath"
	"sort"
)

func GetProjects(datapath string) ([]string, error) {
	dir, err := ioutil.ReadDir(datapath)
	if err != nil {
		return []string{}, err
	}

	var out []string
	for _, d := range dir {
		file := d.Name()
		l.Debug("DirName: ", file)

		if strings.HasPrefix(file, ".") {
			l.Trace(file, " has prefix '.'")
			continue
		}

		ext := filepath.Ext(file)
		name := file[0 : len(file)-len(ext)]

		out = append(out, name)
	}

	sort.Strings(out)
	return out, nil
}
<|endoftext|>


<commit_before>package main

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

type Git interface {
	// GetUpdateRepo either clones the specified repository if it hasn't been cloned yet or simply
	// fetches the latest changes for it. Returns the Repo in any case.
	GetUpdatedRepo(url, repoOwner, repoName string) (Repo, error)
}

type Repo interface {
	Fetch() error
	// Runs `git rebase --interactive --autosquash` for the given refs and automatically saves and closes
	// the editor for interactive rebase.
	RebaseAutosquash(upstreamRef, branchRef string) error
	ForcePushHeadTo(remoteRef string) error
	GetHeadSHA() (string, error)
}

type git struct {
	basePath string
}

// NewGit creates a new Git implementation which will hold all its repos in the specified base path
func NewGit(basePath string) Git {
	return git{basePath}
}

func (g git) repo(path string) Repo {
	return repo{path}
}

func (g git) clone(url, localPath string) (Repo, error) {
	if err := exec.Command("git", "clone", url, localPath).Run(); err != nil {
		return repo{}, fmt.Errorf("failed to clone: %v", err)
	}
	return g.repo(localPath), nil
}

func (g git) GetUpdatedRepo(url, repoOwner, repoName string) (Repo, error) {
	localPath := filepath.Join(g.basePath, repoOwner, repoName)
	exists, err := exists(localPath)
	if err != nil {
		return nil, fmt.Errorf("failed to check if the repo exists locally: %v", err)
	}
	if !exists {
		log.Printf("Cloning %s into %s\n", url, localPath)
		return g.clone(url, localPath)
	}

	log.Printf("Fetching latest changes for %s\n", url)
	repo := g.repo(localPath)
	err = repo.Fetch()
	return repo, err
}

func exists(path string) (bool, error) {
	_, err := os.Stat(path)
	if os.IsNotExist(err) {
		return false, nil
	} else if err != nil {
		return false, err
	}
	return true, nil
}

type repo struct {
	path string
}

func (r repo) RebaseAutosquash(upstreamRef, branchRef string) error {
	// This makes the --interactive rebase not actually interactive
	if err := os.Setenv("GIT_SEQUENCE_EDITOR", "true"); err != nil {
		return fmt.Errorf("failed to change the env variable: %v", err)
	}
	defer os.Unsetenv("GIT_SEQUENCE_EDITOR")

	if err := exec.Command("git", "-C", r.path, "rebase", "--interactive", "--autosquash", upstreamRef, branchRef).Run(); err != nil {
		err = fmt.Errorf("failed to rebase: %v", err)
		log.Println(err, " Trying to clean up.")
		if cleanupErr := exec.Command("git", "-C", r.path, "rebase", "--abort").Run(); cleanupErr != nil {
			log.Println("Also failed to clean up after the failed rebase: ", cleanupErr)
		}
		return err
	}
	return nil
}

func (r repo) Fetch() error {
	if err := exec.Command("git", "-C", r.path, "fetch").Run(); err != nil {
		return fmt.Errorf("failed to fetch: %v", err)
	}
	return nil
}

func (r repo) ForcePushHeadTo(remoteRef string) error {
	if err := exec.Command("git", "-C", r.path, "push", "--force", "origin", "@:"+remoteRef).Run(); err != nil {
		return fmt.Errorf("failed to force push to remote: %v", err)
	}
	return nil
}

func (r repo) GetHeadSHA() (string, error) {
	output, err := exec.Command("git", "-C", r.path, "rev-parse", "@").Output()
	if err != nil {
		return "", fmt.Errorf("failed to get the current HEAD's SHA: %v", err)
	}
	headSHA := strings.TrimSpace(string(output[:]))
	return headSHA, nil
}
<commit_msg>Use mutexes to lock git access<commit_after>package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"sync"
)

type Git interface {
	// GetUpdateRepo either clones the specified repository if it hasn't been cloned yet or simply
	// fetches the latest changes for it. Returns the Repo in any case.
	GetUpdatedRepo(url, repoOwner, repoName string) (Repo, error)
}

type Repo interface {
	Fetch() error
	// Runs `git rebase --interactive --autosquash` for the given refs and automatically saves and closes
	// the editor for interactive rebase.
	RebaseAutosquash(upstreamRef, branchRef string) error
	ForcePushHeadTo(remoteRef string) error
	GetHeadSHA() (string, error)
}

type git struct {
	sync.Mutex
	basePath string
	repos    map[string]repo
}

// NewGit creates a new Git implementation which will hold all its repos in the specified base path
func NewGit(basePath string) Git {
	return git{
		basePath: basePath,
		repos:    make(map[string]repo),
	}
}

func (g git) repo(path string) Repo {
	existingRepo, exists := g.repos[path]
	if !exists {
		newRepo := repo{path: path}
		g.repos[path] = newRepo
		return newRepo
	}
	return existingRepo
}

func (g git) clone(url, localPath string) (Repo, error) {
	if err := exec.Command("git", "clone", url, localPath).Run(); err != nil {
		return repo{}, fmt.Errorf("failed to clone: %v", err)
	}
	return g.repo(localPath), nil
}

func (g git) GetUpdatedRepo(url, repoOwner, repoName string) (Repo, error) {
	g.Lock()
	defer g.Unlock()

	localPath := filepath.Join(g.basePath, repoOwner, repoName)
	exists, err := exists(localPath)
	if err != nil {
		return nil, fmt.Errorf("failed to check if the repo exists locally: %v", err)
	}
	if !exists {
		log.Printf("Cloning %s into %s\n", url, localPath)
		return g.clone(url, localPath)
	}

	log.Printf("Fetching latest changes for %s\n", url)
	repo := g.repo(localPath)
	err = repo.Fetch()
	return repo, err
}

func exists(path string) (bool, error) {
	_, err := os.Stat(path)
	if os.IsNotExist(err) {
		return false, nil
	} else if err != nil {
		return false, err
	}
	return true, nil
}

type repo struct {
	sync.Mutex
	path string
}

func (r repo) RebaseAutosquash(upstreamRef, branchRef string) error {
	r.Lock()
	defer r.Unlock()

	// This makes the --interactive rebase not actually interactive
	if err := os.Setenv("GIT_SEQUENCE_EDITOR", "true"); err != nil {
		return fmt.Errorf("failed to change the env variable: %v", err)
	}
	defer os.Unsetenv("GIT_SEQUENCE_EDITOR")

	if err := exec.Command("git", "-C", r.path, "rebase", "--interactive", "--autosquash", upstreamRef, branchRef).Run(); err != nil {
		err = fmt.Errorf("failed to rebase: %v", err)
		log.Println(err, " Trying to clean up.")
		if cleanupErr := exec.Command("git", "-C", r.path, "rebase", "--abort").Run(); cleanupErr != nil {
			log.Println("Also failed to clean up after the failed rebase: ", cleanupErr)
		}
		return err
	}
	return nil
}

func (r repo) Fetch() error {
	r.Lock()
	defer r.Unlock()

	if err := exec.Command("git", "-C", r.path, "fetch").Run(); err != nil {
		return fmt.Errorf("failed to fetch: %v", err)
	}
	return nil
}

func (r repo) ForcePushHeadTo(remoteRef string) error {
	r.Lock()
	defer r.Unlock()

	if err := exec.Command("git", "-C", r.path, "push", "--force", "origin", "@:"+remoteRef).Run(); err != nil {
		return fmt.Errorf("failed to force push to remote: %v", err)
	}
	return nil
}

func (r repo) GetHeadSHA() (string, error) {
	r.Lock()
	defer r.Unlock()

	output, err := exec.Command("git", "-C", r.path, "rev-parse", "@").Output()
	if err != nil {
		return "", fmt.Errorf("failed to get the current HEAD's SHA: %v", err)
	}
	headSHA := strings.TrimSpace(string(output[:]))
	return headSHA, nil
}
<|endoftext|>


<commit_before>package glu

// #cgo pkg-config: glu
//
// #include <GL/glu.h>
//
import "C"
import "github.com/banthar/gl"
import "unsafe"

func Build2DMipmaps(target gl.GLenum, internalFormat int, width, height int, format gl.GLenum, data interface{}) int {
	t, p := gl.GetGLenumType(data)
	return int(C.gluBuild2DMipmaps(
		C.GLenum(target),
		C.GLint(internalFormat),
		C.GLsizei(width),
		C.GLsizei(height),
		C.GLenum(format),
		C.GLenum(t),
		p,
	))
}

func Perspective(fovy, aspect, zNear, zFar float64) {
	C.gluPerspective(
		C.GLdouble(fovy),
		C.GLdouble(aspect),
		C.GLdouble(zNear),
		C.GLdouble(zFar),
	)
}

func LookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ float64) {
	C.gluLookAt(
		C.GLdouble(eyeX),
		C.GLdouble(eyeY),
		C.GLdouble(eyeZ),
		C.GLdouble(centerX),
		C.GLdouble(centerY),
		C.GLdouble(centerZ),
		C.GLdouble(upX),
		C.GLdouble(upY),
		C.GLdouble(upZ),
	)
}

func UnProject(winX, winY, winZ float64, model, proj *[16]float64, view *[4]int32) (float64, float64, float64) {
	var ox, oy, oz C.GLdouble

	m := (*C.GLdouble)(unsafe.Pointer(model))
	p := (*C.GLdouble)(unsafe.Pointer(proj))
	v := (*C.GLint)(unsafe.Pointer(view))

	C.gluUnProject(
		C.GLdouble(winX),
		C.GLdouble(winY),
		C.GLdouble(winZ),
		m,
		p,
		v,
		&ox,
		&oy,
		&oz,
	)

	return float64(ox), float64(oy), float64(oz)
}

func Project(projX, projY, projZ float64, model, proj *[16]float64, view *[4]int32) (float64, float64, float64) {
	var ox, oy, oz C.GLdouble

	m := (*C.GLdouble)(unsafe.Pointer(model))
	p := (*C.GLdouble)(unsafe.Pointer(proj))
	v := (*C.GLint)(unsafe.Pointer(view))

	C.gluProject(
		C.GLdouble(projX),
		C.GLdouble(projY),
		C.GLdouble(projZ),
		m,
		p,
		v,
		&ox,
		&oy,
		&oz,
	)

	return float64(ox), float64(oy), float64(oz)
}

func NewQuadric() unsafe.Pointer {
	return unsafe.Pointer(C.gluNewQuadric())
}

func Sphere(q unsafe.Pointer, radius float32, slices, stacks int) {
	C.gluSphere((*[0]byte)(q), C.GLdouble(radius), C.GLint(slices), C.GLint(stacks))
}

func Cylinder(q unsafe.Pointer, base, top, height float32, slices, stacks int) {
	C.gluCylinder((*[0]byte)(q), C.GLdouble(base), C.GLdouble(top), C.GLdouble(height), C.GLint(slices), C.GLint(stacks))
}

func Disk(q unsafe.Pointer, inner, outer float32, slices, loops int) {
	C.gluDisk((*[0]byte)(q), C.GLdouble(inner), C.GLdouble(outer), C.GLint(slices), C.GLint(loops))
}<commit_msg>Add ErrorString(error gl.GLenum)<commit_after>package glu

// #cgo pkg-config: glu
//
// #include <GL/glu.h>
//
import "C"
import (
	"errors"
	"unsafe"

	"github.com/banthar/gl"
)

func ErrorString(error gl.GLenum) (string, error) {
	e := unsafe.Pointer(C.gluErrorString(C.GLenum(error)))
	if e == nil {
		return "", errors.New("Invalid GL error code")
	}
	return C.GoString((*C.char)(e)), nil
}

func Build2DMipmaps(target gl.GLenum, internalFormat int, width, height int, format gl.GLenum, data interface{}) int {
	t, p := gl.GetGLenumType(data)
	return int(C.gluBuild2DMipmaps(
		C.GLenum(target),
		C.GLint(internalFormat),
		C.GLsizei(width),
		C.GLsizei(height),
		C.GLenum(format),
		C.GLenum(t),
		p,
	))
}

func Perspective(fovy, aspect, zNear, zFar float64) {
	C.gluPerspective(
		C.GLdouble(fovy),
		C.GLdouble(aspect),
		C.GLdouble(zNear),
		C.GLdouble(zFar),
	)
}

func LookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ float64) {
	C.gluLookAt(
		C.GLdouble(eyeX),
		C.GLdouble(eyeY),
		C.GLdouble(eyeZ),
		C.GLdouble(centerX),
		C.GLdouble(centerY),
		C.GLdouble(centerZ),
		C.GLdouble(upX),
		C.GLdouble(upY),
		C.GLdouble(upZ),
	)
}

func UnProject(winX, winY, winZ float64, model, proj *[16]float64, view *[4]int32) (float64, float64, float64) {
	var ox, oy, oz C.GLdouble

	m := (*C.GLdouble)(unsafe.Pointer(model))
	p := (*C.GLdouble)(unsafe.Pointer(proj))
	v := (*C.GLint)(unsafe.Pointer(view))

	C.gluUnProject(
		C.GLdouble(winX),
		C.GLdouble(winY),
		C.GLdouble(winZ),
		m,
		p,
		v,
		&ox,
		&oy,
		&oz,
	)

	return float64(ox), float64(oy), float64(oz)
}

func Project(projX, projY, projZ float64, model, proj *[16]float64, view *[4]int32) (float64, float64, float64) {
	var ox, oy, oz C.GLdouble

	m := (*C.GLdouble)(unsafe.Pointer(model))
	p := (*C.GLdouble)(unsafe.Pointer(proj))
	v := (*C.GLint)(unsafe.Pointer(view))

	C.gluProject(
		C.GLdouble(projX),
		C.GLdouble(projY),
		C.GLdouble(projZ),
		m,
		p,
		v,
		&ox,
		&oy,
		&oz,
	)

	return float64(ox), float64(oy), float64(oz)
}

func NewQuadric() unsafe.Pointer {
	return unsafe.Pointer(C.gluNewQuadric())
}

func Sphere(q unsafe.Pointer, radius float32, slices, stacks int) {
	C.gluSphere((*[0]byte)(q), C.GLdouble(radius), C.GLint(slices), C.GLint(stacks))
}

func Cylinder(q unsafe.Pointer, base, top, height float32, slices, stacks int) {
	C.gluCylinder((*[0]byte)(q), C.GLdouble(base), C.GLdouble(top), C.GLdouble(height), C.GLint(slices), C.GLint(stacks))
}

func Disk(q unsafe.Pointer, inner, outer float32, slices, loops int) {
	C.gluDisk((*[0]byte)(q), C.GLdouble(inner), C.GLdouble(outer), C.GLint(slices), C.GLint(loops))
}<|endoftext|>


<commit_before>// Copyright 2015 Robert S. Gerus. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package main

/*
// taken directly from https://github.com/Igneous/libxname/blob/master/xname.c
#cgo LDFLAGS: -lX11
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>

int xname(const char *msg) {
	Display *dpy;
	Window rootwin;
	int scr;

	if(!(dpy=XOpenDisplay(NULL))) {
		fprintf(stderr, "ERROR: could not open display\n");
		exit(1);
	}

	scr = DefaultScreen(dpy);
	rootwin = RootWindow(dpy, scr);

	XStoreName(dpy, rootwin, msg);
	XCloseDisplay(dpy);

	return 0;
}
*/
import "C"

import (
	"fmt"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"log"
	"os"
	"strconv"
	"strings"
	"time"
)

type statusbarItem struct {
	Name   string            `yaml:"name"`
	Period int               `yaml:"period"`
	Type   string            `yaml:"type"`
	Args   map[string]string `yaml:"args"`
}

type gsdConfig struct {
	Separator string          `yaml:"separator"`
	Items     []statusbarItem `yaml:"items"`
}

var config gsdConfig
var statusbar []string

func timestamp(args map[string]string) string {
	return time.Now().Format(args["format"])
}

func fileReader(args map[string]string) string {
	buf, err := ioutil.ReadFile(args["path"])
	if err != nil {
		log.Println("Error reading", args["path"], err)
		return ""
	}
	content := strings.TrimSpace(string(buf))

	if args["format"] != "" {
		content = fmt.Sprintf(args["format"], content)
	}

	if args["range_from"] != "" && args["range_to"] != "" && args["separator"] != "" {
		from, _ := strconv.Atoi(args["range_from"])
		to, _ := strconv.Atoi(args["range_to"])
		content = strings.Join(strings.Split(content, args["separator"])[from:to], args["separator"])
	}

	return content
}

func main() {
	if len(os.Args) < 2 {
		log.Fatalln("Usage:", os.Args[0], "<configuration file>")
	}

	data, err := ioutil.ReadFile(os.Args[1])
	if err != nil {
		log.Fatalln("Error reading configuration file:", err)
	}

	if err := yaml.Unmarshal(data, &config); err != nil {
		log.Fatalln("Error parsing configuration file:", err)
	}

	statusbar = make([]string, len(config.Items))

	for i := 0; ; i++ {
		for pos, item := range config.Items {
			if (i % item.Period) == 0 {
				switch item.Type {
				case "fileReader":
					statusbar[pos] = fileReader(item.Args)
				case "timestamp":
					statusbar[pos] = timestamp(item.Args)
				default:
					log.Fatalln("Unknown item type", item.Type)
				}
			}
		}

		C.xname(C.CString(strings.Join(statusbar, config.Separator)))
		time.Sleep(time.Duration(1) * time.Second)
	}
}
<commit_msg>Add rudimentary wifi status support and use "flag" for parsing arguments.<commit_after>// Copyright 2015 Robert S. Gerus. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package main

/*
// taken directly from https://github.com/Igneous/libxname/blob/master/xname.c
#cgo LDFLAGS: -lX11
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>

int xname(const char *msg) {
	Display *dpy;
	Window rootwin;
	int scr;

	if(!(dpy=XOpenDisplay(NULL))) {
		fprintf(stderr, "ERROR: could not open display\n");
		exit(1);
	}

	scr = DefaultScreen(dpy);
	rootwin = RootWindow(dpy, scr);

	XStoreName(dpy, rootwin, msg);
	XCloseDisplay(dpy);

	return 0;
}
*/
import "C"

import (
	"flag"
	"fmt"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"log"
	"os"
	"path"
	"strconv"
	"strings"
	"time"

	"github.com/mdlayher/wifi"
)

type statusbarItem struct {
	Name   string            `yaml:"name"`
	Period int               `yaml:"period"`
	Type   string            `yaml:"type"`
	Args   map[string]string `yaml:"args"`
}

type gsdConfig struct {
	Separator string          `yaml:"separator"`
	Items     []statusbarItem `yaml:"items"`
}

var config gsdConfig
var statusbar []string

func timestamp(args map[string]string) string {
	return time.Now().Format(args["format"])
}

func fileReader(args map[string]string) string {
	buf, err := ioutil.ReadFile(args["path"])
	if err != nil {
		log.Println("Error reading", args["path"], err)
		return ""
	}
	content := strings.TrimSpace(string(buf))

	if args["format"] != "" {
		content = fmt.Sprintf(args["format"], content)
	}

	if args["range_from"] != "" && args["range_to"] != "" && args["separator"] != "" {
		from, _ := strconv.Atoi(args["range_from"])
		to, _ := strconv.Atoi(args["range_to"])
		content = strings.Join(strings.Split(content, args["separator"])[from:to], args["separator"])
	}

	return content
}

func wifiSSID(wifiClient *wifi.Client, args map[string]string) string {
	ifaces, err := wifiClient.Interfaces()
	if err != nil {
		return err.Error()
	}

	for _, iface := range ifaces {
		if iface.Name == args["interface"] {
			bss, err := wifiClient.BSS(iface)
			if err != nil {
				return err.Error()
			}

			return bss.SSID
		}
	}
	return "NOPE"
}

var configPath string
var wifiFlag bool

func init() {
	flag.StringVar(&configPath, "config", path.Join(os.Getenv("HOME"), ".gsd.conf.yaml"), "configuration file path")
	flag.BoolVar(&wifiFlag, "wifi", true, "enable wifi status")
}

func main() {
	flag.Parse()
	var wifiClient *wifi.Client

	data, err := ioutil.ReadFile(configPath)
	if err != nil {
		log.Fatalln("Error reading configuration file:", err)
	}

	if err := yaml.Unmarshal(data, &config); err != nil {
		log.Fatalln("Error parsing configuration file:", err)
	}

	if wifiFlag {
		wifiClient, err = wifi.New()
	}

	statusbar = make([]string, len(config.Items))

	for i := 0; ; i++ {
		for pos, item := range config.Items {
			if (i % item.Period) == 0 {
				switch item.Type {
				case "fileReader":
					statusbar[pos] = fileReader(item.Args)
				case "timestamp":
					statusbar[pos] = timestamp(item.Args)
				case "wifi_ssid":
					if wifiFlag {
						statusbar[pos] = wifiSSID(wifiClient, item.Args)
					} else {
						statusbar[pos] = "NOPE"
					}
				default:
					log.Fatalln("Unknown item type", item.Type)
				}
			}
		}

		C.xname(C.CString(strings.Join(statusbar, config.Separator)))
		time.Sleep(time.Duration(1) * time.Second)
	}
}
<|endoftext|>


<commit_before>package probstruct

import(
  "errors"
  "math"
  "math/bits"
)

// N = number of buckets in registry
// b = number of significant bits used assigning incoming data
// leading zeros in remaining binary value are used to estimate probability
// buckets = estimators with Length of N
type HLL struct {
  m uint32
  p uint
  // each bucket will hold max( count_zeroes + 1 ) in 64bit uint with 4..16 bits already derived
  // thus, uint8 cannot overflow
  buckets []uint8
  alpha float64

  cardinality uint64

  // some data points are already globally unique unsigned integers, e.g. IPv4 addresses and ports
  // thus, alpha correction for hash collisions is not needed, and we will have to adjust for lenth when calculating buckets
  hashing bool
  // switch between 32 and 64 bit input items
  // by default bitwise operations assumes unsigned 64bit hash input
  // breaks when counting 32bit globally unique values
  bitness uint
  // select hashing method, in line with bloom and cms implementations
  hash int
}

// Init new HLL instance
// user should choose between 4 and 16 significant bits
// each bit increases computational complexity by order of magnitude
// 16 = 65536, 15 = 32768, 14 = 16384, etc
// x << y == x * 2**y
func InitHLL(precision uint, hashing bool, hash int) (h *HLL, err error) {
  if precision < 4 || precision > 16 {
    return nil, errors.New("precision must be integer between 4 and 16")
  }
  h = &HLL{
    p:  precision,
    m:  1 << precision,
    hashing:  hashing,
    hash: hash,
  }
  h.buckets = make([]uint8, h.m)
  if h.hashing == false {
    h.bitness = 32
    h.alpha = 1
  } else {
    h.bitness = 64
    // Magic numbers for hash collision correction
    switch h.m {
    case 16:
      h.alpha = 0.673
    case 32:
      h.alpha = 0.697
    case 64:
      h.alpha = 0.709
    default:
      h.alpha = 0.7213 / ( 1 + 1.079 / float64(h.m) )
    }
  }
  return h, err
}

func (h *HLL) AddString(item string) *HLL {
  return h.AddHash([]byte(item))
}

// Add converts databyte item into uint64 and adds position of first true boolean after bitwise header into appropriate bucket
func (h *HLL) AddHash(item []byte) *HLL {
  hash := genHashBase(item, h.hash)[0]
  return h.Add(hash)
}

func (h *HLL) Add(hash uint64) *HLL {
  diff := h.bitness - h.p
  index := hash >> diff
  tail := hash << h.p
  count := uint8(bits.LeadingZeros64(tail)) + 1

  if count > h.buckets[index] {
    h.buckets[index] = count
  }
  return h
}

func (h *HLL) Count() *HLL {
  Z := float64(0)
  for _, c := range h.buckets {
    if c > 0 {
      Z += float64( 1 / math.Pow( float64(2), float64(c) ) )
    }
  }
  Z = 1 / Z
  count := h.alpha * math.Pow( float64(h.m), 2) * Z
  h.cardinality = uint64( math.Floor(count) )
  return h
}

func (h *HLL) GetCardinality() uint64 {
  return h.cardinality
}

func (h *HLL) GetCounters() uint32 {
  return h.m
}
<commit_msg>Damn you strict typing<commit_after>package probstruct

import(
  "errors"
  "math"
  "math/bits"
)

// N = number of buckets in registry
// b = number of significant bits used assigning incoming data
// leading zeros in remaining binary value are used to estimate probability
// buckets = estimators with Length of N
type HLL struct {
  m uint32
  p uint
  // each bucket will hold max( count_zeroes + 1 ) in 64bit uint with 4..16 bits already derived
  // thus, uint8 cannot overflow
  buckets []uint8
  alpha float64

  cardinality uint64

  // some data points are already globally unique unsigned integers, e.g. IPv4 addresses and ports
  // thus, alpha correction for hash collisions is not needed, and we will have to adjust for lenth when calculating buckets
  hashing bool
  // switch between 32 and 64 bit input items
  // by default bitwise operations assumes unsigned 64bit hash input
  // breaks when counting 32bit globally unique values
  bitness uint
  // select hashing method, in line with bloom and cms implementations
  hash int
}

// Init new HLL instance
// user should choose between 4 and 16 significant bits
// each bit increases computational complexity by order of magnitude
// 16 = 65536, 15 = 32768, 14 = 16384, etc
// x << y == x * 2**y
func InitHLL(precision uint, hashing bool, hash int) (h *HLL, err error) {
  if precision < 4 || precision > 16 {
    return nil, errors.New("precision must be integer between 4 and 16")
  }
  h = &HLL{
    p:  precision,
    m:  1 << precision,
    hashing:  hashing,
    hash: hash,
  }
  h.buckets = make([]uint8, h.m)
  if h.hashing == false {
    h.bitness = 32
    h.alpha = 1
  } else {
    h.bitness = 64
    // Magic numbers for hash collision correction
    switch h.m {
    case 16:
      h.alpha = 0.673
    case 32:
      h.alpha = 0.697
    case 64:
      h.alpha = 0.709
    default:
      h.alpha = 0.7213 / ( 1 + 1.079 / float64(h.m) )
    }
  }
  return h, err
}

func (h *HLL) AddString(item string) *HLL {
  return h.AddHash([]byte(item))
}

// Add converts databyte item into uint64 and adds position of first true boolean after bitwise header into appropriate bucket
func (h *HLL) AddHash(item []byte) *HLL {
  hash := genHashBase(item, h.hash)[0]
  return h.Add64(hash)
}

func (h *HLL) Add64(hash uint64) *HLL {
  diff := h.bitness - h.p
  index := hash >> diff
  tail := hash << h.p
  count := uint8(bits.LeadingZeros64(tail)) + 1

  if count > h.buckets[index] {
    h.buckets[index] = count
  }
  return h
}

func (h *HLL) Add32(hash uint32) *HLL {
  diff := h.bitness - h.p
  index := hash >> diff
  tail := hash << h.p
  count := uint8(bits.LeadingZeros32(tail)) + 1

  if count > h.buckets[index] {
    h.buckets[index] = count
  }
  return h
}

func (h *HLL) Count() *HLL {
  Z := float64(0)
  for _, c := range h.buckets {
    if c > 0 {
      Z += float64( 1 / math.Pow( float64(2), float64(c) ) )
    }
  }
  Z = 1 / Z
  count := h.alpha * math.Pow( float64(h.m), 2) * Z
  h.cardinality = uint64( math.Floor(count) )
  return h
}

func (h *HLL) GetCardinality() uint64 {
  return h.cardinality
}

func (h *HLL) GetCounters() uint32 {
  return h.m
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/gob"
	"encoding/hex"
	"flag"
	"fmt"
	"github.com/bmizerany/pat"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path"
)

type CacheEntry struct {
	ContentType string
	Body        []byte
}

type ReadRequest struct {
	key string
	ch  chan *CacheEntry
}

type SaveRequest struct {
	key   string
	entry *CacheEntry
}

var readChan chan ReadRequest
var saveChan chan SaveRequest

// The directory for caching files
var directory string

// The secret for checking the HMAC on requests
var secret []byte

// Read an entry of cache from the disk and send it to the chan
func readEntryFromDisk(filename string, ch chan *CacheEntry) {
	f, err := os.Open(filename)
	if err != nil {
		ch <- nil
		return
	}
	defer f.Close()

	entry := &CacheEntry{}
	dec := gob.NewDecoder(f)
	err = dec.Decode(entry)
	if err != nil {
		entry = nil
	}
	ch <- entry
}

// Save an entry of cache on the disk
func saveEntryToDisk(filename string, entry *CacheEntry) {
	dirname := path.Dir(filename)
	err := os.MkdirAll(dirname, 0755)
	if err != nil {
		return
	}

	f, err := os.OpenFile(filename+".tmp", os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0644)
	if err != nil {
		return
	}
	defer f.Close()

	enc := gob.NewEncoder(f)
	err = enc.Encode(entry)
	if err != nil {
		os.Remove(filename + ".tmp")
		return
	}
	err = os.Rename(filename+".tmp", filename)
	if err != nil {
		os.Remove(filename + ".tmp")
		return
	}
}

// Run the cache in its own goroutine
func runCache() {
	for {
		select {
		case read := <-readChan:
			filename := path.Join(directory, read.key)
			go readEntryFromDisk(filename, read.ch)
		case save := <-saveChan:
			filename := path.Join(directory, save.key)
			go saveEntryToDisk(filename, save.entry)
		}
	}
}

// Generate a key for cache from a string
func generateKeyForCache(s string) string {
	h := sha1.New()
	io.WriteString(h, s)
	key := h.Sum(nil)

	// Use 3 levels of hasing to avoid having too many files in the same directory
	return fmt.Sprintf("%x/%x/%x/%x", key[0:1], key[1:2], key[2:3], key[3:])
}

// Fetch image from cache
func fetchImageFromCache(key string) (contentType string, body []byte, ok bool) {
	ch := make(chan *CacheEntry)
	readChan <- ReadRequest{key, ch}
	entry := <-ch
	if ok = entry != nil; ok {
		contentType = entry.ContentType
		body = entry.Body
	}
	return
}

// Save the body and the headers in cache
func saveImageInCache(key string, contentType string, body []byte) {
	entry := CacheEntry{contentType, body}
	saveChan <- SaveRequest{key, &entry}
}

// Fetch the image from the distant server
func fetchImageFromServer(url string) (contentType string, body []byte, err error) {
	res, err := http.Get(url)
	if err != nil {
		return
	}

	defer res.Body.Close()
	body, err = ioutil.ReadAll(res.Body)
	if err != nil {
		return
	}
	contentType = res.Header.Get("Content-Type")
	fmt.Printf("Content-Type = %s\n", contentType)

	return
}

// Fetch image from cache if available, or from the server
func fetchImage(url string) (contentType string, body []byte, err error) {
	key := generateKeyForCache(url)

	contentType, body, ok := fetchImageFromCache(key)
	if ok {
		return
	}

	contentType, body, err = fetchImageFromServer(url)
	if err == nil {
		go saveImageInCache(key, contentType, body)
	}

	return
}

// Decode the URL and compute the associated HMAC
func decodeUrl(encoded_url string) (url []byte, actual string, err error) {
	url, err = hex.DecodeString(encoded_url)
	if err != nil {
		return
	}

	h := hmac.New(sha1.New, secret)
	_, err = h.Write(url)
	if err != nil {
		return
	}
	actual = fmt.Sprintf("%x", h.Sum(nil))

	return
}

// Fetch the image from the URL (or cache) and respond with it
func Img(w http.ResponseWriter, r *http.Request) {
	expected := r.URL.Query().Get(":hmac")
	encoded_url := r.URL.Query().Get(":encoded_url")
	url, actual, err := decodeUrl(encoded_url)
	if err != nil {
		http.Error(w, "Invalid parameters", 400)
		return
	}
	if expected != actual {
		http.Error(w, "Invalid HMAC", 403)
		return
	}
	contentType, body, err := fetchImage(string(url))
	if err != nil {
		http.NotFound(w, r)
		return
	}
	w.Header().Add("Content-Type", contentType)
	w.Write(body)
}

// Returns 200 OK if the server is running (for monitoring)
func Status(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "OK")
}

func main() {
	// Parse the command-line
	var addr string
	var secr string
	flag.StringVar(&addr, "a", "127.0.0.1:8000", "Bind to this address:port")
	flag.StringVar(&secr, "s", "252c38cdb9f638908fab5df7263d156c759d590b1251785fa612e7874ee9bbcc32a61f8d795e7593ca31f8f47396c497b215e1abde6e947d7e25772f30115a7e", "The secret for HMAC check")
	flag.StringVar(&directory, "d", "cache", "The directory for the caching files")
	flag.Parse()
	secret = []byte(secr)

	// Start the cache
	readChan = make(chan ReadRequest)
	saveChan = make(chan SaveRequest)
	go runCache()

	// Routing
	m := pat.New()
	m.Get("/status", http.HandlerFunc(Status))
	m.Get("/img/:hmac/:encoded_url", http.HandlerFunc(Img))
	http.Handle("/", m)

	// Start the HTTP server
	fmt.Printf("Listening on http://%s/\n", addr)
	err := http.ListenAndServe(addr, nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
<commit_msg>Refactoring<commit_after>package main

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/gob"
	"encoding/hex"
	"flag"
	"fmt"
	"github.com/bmizerany/pat"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path"
)

type CacheEntry struct {
	ContentType string
	Body        []byte
}

// The directory for caching files
var directory string

// The secret for checking the HMAC on requests
var secret []byte

// Fetch image from cache
func fetchImageFromCache(filename string) (contentType string, body []byte, ok bool) {
	ok = false

	f, err := os.Open(filename)
	if err != nil {
		return
	}
	defer f.Close()

	var entry CacheEntry
	dec := gob.NewDecoder(f)
	err = dec.Decode(&entry)
	if err != nil {
		log.Printf("Error while decoding %s\n", filename)
	} else {
		contentType = entry.ContentType
		body = entry.Body
		ok = true
	}

	return
}

// Save the body and the headers in cache (on disk)
func saveImageInCache(filename string, contentType string, body []byte) {
	dirname := path.Dir(filename)
	err := os.MkdirAll(dirname, 0755)
	if err != nil {
		return
	}

	f, err := os.OpenFile(filename+".tmp", os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0644)
	if err != nil {
		log.Printf("Error while opening %s\n", filename)
		return
	}
	defer f.Close()

	enc := gob.NewEncoder(f)
	err = enc.Encode(CacheEntry{contentType, body})
	if err != nil {
		log.Printf("Error while encoding %s\n", filename)
		os.Remove(filename + ".tmp")
		return
	}
	err = os.Rename(filename+".tmp", filename)
	if err != nil {
		log.Printf("Error while renaming %s\n", filename)
		os.Remove(filename + ".tmp")
	}
}

// Generate a key for cache from a string
func generateKeyForCache(s string) string {
	h := sha1.New()
	io.WriteString(h, s)
	key := h.Sum(nil)

	// Use 3 levels of hasing to avoid having too many files in the same directory
	return fmt.Sprintf("%s/%x/%x/%x/%x", directory, key[0:1], key[1:2], key[2:3], key[3:])
}

// Fetch the image from the distant server
func fetchImageFromServer(url string) (contentType string, body []byte, err error) {
	res, err := http.Get(url)
	if err != nil {
		return
	}

	defer res.Body.Close()
	body, err = ioutil.ReadAll(res.Body)
	if err != nil {
		return
	}
	contentType = res.Header.Get("Content-Type")
	log.Printf("Fetch %s (%s)\n", url, contentType)

	return
}

// Fetch image from cache if available, or from the server
func fetchImage(url string) (contentType string, body []byte, err error) {
	key := generateKeyForCache(url)

	contentType, body, ok := fetchImageFromCache(key)
	if ok {
		return
	}

	contentType, body, err = fetchImageFromServer(url)
	if err == nil {
		go saveImageInCache(key, contentType, body)
	}

	return
}

// Decode the URL and compute the associated HMAC
func decodeUrl(encoded_url string) (url []byte, actual string, err error) {
	url, err = hex.DecodeString(encoded_url)
	if err != nil {
		return
	}

	h := hmac.New(sha1.New, secret)
	_, err = h.Write(url)
	if err != nil {
		return
	}
	actual = fmt.Sprintf("%x", h.Sum(nil))

	return
}

// Fetch the image from the URL (or cache) and respond with it
func Img(w http.ResponseWriter, r *http.Request) {
	expected := r.URL.Query().Get(":hmac")
	encoded_url := r.URL.Query().Get(":encoded_url")
	url, actual, err := decodeUrl(encoded_url)
	if err != nil {
		log.Printf("Invalid URL %s%s\n", encoded_url)
		http.Error(w, "Invalid parameters", 400)
		return
	}
	if expected != actual {
		log.Printf("Invalid HMAC expected=%s actual=%s\n", expected, actual)
		http.Error(w, "Invalid HMAC", 403)
		return
	}
	contentType, body, err := fetchImage(string(url))
	if err != nil {
		http.NotFound(w, r)
		return
	}
	w.Header().Add("Content-Type", contentType)
	w.Write(body)
}

// Returns 200 OK if the server is running (for monitoring)
func Status(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "OK")
}

func main() {
	// Parse the command-line
	var addr string
	var secr string
	flag.StringVar(&addr, "a", "127.0.0.1:8000", "Bind to this address:port")
	flag.StringVar(&secr, "s", "252c38cdb9f638908fab5df7263d156c759d590b1251785fa612e7874ee9bbcc32a61f8d795e7593ca31f8f47396c497b215e1abde6e947d7e25772f30115a7e", "The secret for HMAC check")
	flag.StringVar(&directory, "d", "cache", "The directory for the caching files")
	flag.Parse()
	secret = []byte(secr)

	// Routing
	m := pat.New()
	m.Get("/status", http.HandlerFunc(Status))
	m.Get("/img/:hmac/:encoded_url", http.HandlerFunc(Img))
	http.Handle("/", m)

	// Start the HTTP server
	log.Printf("Listening on http://%s/\n", addr)
	err := http.ListenAndServe(addr, nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
<|endoftext|>


<commit_before>// Copyright (C) 2015 Thomas de Zeeuw.
//
// Licensed under the MIT license that can be found in the LICENSE file.

// Package ini parses an ini formatted file. The parsed configuration can be
// decoded into a variable or used directly.
package ini

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"reflect"
	"sort"
	"strconv"
	"strings"
	"unicode"
)

// Global is the section name for key-values not under a section. It is used
// for retrieving key-value pairs in the "global" section, or not under any
// other section.
//
//	value := config[ini.Global]["key"]
//	value2, found := config[ini.Global]["key2"]
const Global = ""

// Name for the global section in errors.
const globalName = "global"

// Config holds all key-value pairs under sections. To retrieve a key-value
// pair you can use:
//
//	value := config["section"]["key"]
//	value2, found := config["section"]["key2"]
//
// The same as you would for a map. For retrieving key-value pairs not in any
// section, or the "global" section, you can use the `ini.Global` constant,
// like so:
//
//	value := config[ini.Global]["key"]
//	value2, found := config[ini.Global]["key2"]
type Config map[string]map[string]string

// String returns an ini formatted configuration, ready to be written to a file.
func (c *Config) String() string {
	return c.buffer().String()
}

// Bytes returns an ini formatted configuration, ready to be written to a file.
func (c *Config) Bytes() []byte {
	return c.buffer().Bytes()
}

// WriteTo writes the configuration to the writer in the ini format.
func (c *Config) WriteTo(w io.Writer) (int64, error) {
	return c.buffer().WriteTo(w)
}

// Buffer creates a `bytes.Buffer` with an ini formatted configuration.
func (c *Config) buffer() *bytes.Buffer {
	var result bytes.Buffer

	sections := getConfigSectionsAlpha(*c)
	for _, sectionName := range sections {
		if sectionName != Global {
			result.WriteString("[" + sectionName + "]\n")
		}

		section := (*c)[sectionName]
		keys := getMapsKeysAlpha(section)
		for _, key := range keys {
			value := strconv.Quote(section[key])
			key = strconv.Quote(key)
			result.WriteString(key + "=" + value + "\n")
		}
		result.WriteString("\n")
	}

	return &result
}

func getMapsKeysAlpha(m map[string]string) []string {
	keys := make([]string, 0, len(m))
	for key := range m {
		keys = append(keys, key)
	}
	sort.Strings(keys)
	return keys
}

type fieldCombo struct {
	value reflect.Value
	field reflect.StructField
}

// Decode decodes a configuration into a struct. Any properties to be set need
// to be public. Keys are renamed, whitespace is removed and keys start with a
// capaital, like so:
//
//	"my key" -> "MyKey"
//
// Slices are supported by using a comma separated list, like so:
//
//	"string1, string2" -> []string{"string1", "string2"}
//	"1, 2, 3" -> []int{1, 2, 3}
//
// Booleans are supported aswell:
//
//	"1, t, T, TRUE, true, True" -> true
//	"0, f, F, FALSE, false, False" -> false
//
// Time is supported with the following formats:
//
//	"2006-01-02", "2006-01-02 15:04", "2006-01-02 15:04:05", time.RFC3339,
//	time.RFC1123 and time.RFC822
//
// Duration is also supported, see `time.ParseDuration` for the documentation.
//
// *Note underneath Decode uses the reflect package which isn't great for
// performance, so use it with care.
func (c *Config) Decode(dst interface{}) error {
	valuePtr := reflect.ValueOf(dst)
	value := reflect.Indirect(valuePtr)

	// If it's not a pointer we can't change the original value and if it's not a
	// struct we can't set/change any keys on it, in either case we can't do
	// anything with the value.
	if valuePtr.Kind() != reflect.Ptr || value.Kind() != reflect.Struct {
		return errors.New("ini: Config.Decode requires a pointer to a struct")
	}

	dstType := value.Type()
	for i := value.NumField() - 1; i >= 0; i-- {
		field := value.Field(i)
		if !field.IsValid() || !field.CanSet() {
			continue
		}

		strField := dstType.Field(i)
		var fields []fieldCombo
		var sectionNames = []string{""}

		structFieldType := field.Type()
		if kind := field.Kind(); kind == reflect.Struct &&
			structFieldType != typeDuration && structFieldType != typeTime {
			sectionName := strField.Tag.Get("ini")
			if sectionName != "" {
				sectionNames[0] = sectionName
			} else {
				sectionNames = possibleNames(strField.Name)
			}

			for i := field.NumField() - 1; i >= 0; i-- {
				structField := field.Field(i)
				if !structField.IsValid() || !structField.CanSet() {
					continue
				}
				structFieldType := structFieldType.Field(i)
				fields = append(fields, fieldCombo{structField, structFieldType})
			}
		} else {
			fields = []fieldCombo{{field, strField}}
		}

		for _, combo := range fields {
			value := combo.value
			field := combo.field

			var keys []string
			if key := field.Tag.Get("ini"); key != "" {
				keys = []string{key}
			} else {
				keys = possibleNames(field.Name)
			}

			if err := c.trySetReflect(sectionNames, keys, value); err != nil {
				return err
			}
		}
	}

	return nil
}

// TrySetReflect tries the givens section and keys combination to get the value
// from the config and then sets the field if a value if found.
func (c *Config) trySetReflect(sectionNames []string, keys []string, keyValue reflect.Value) error {
	for _, sectionName := range sectionNames {
		section := (*c)[sectionName]
		if len(section) == 0 {
			continue
		}

		for _, key := range keys {
			value, ok := section[key]
			if !ok {
				continue
			}

			if err := setReflectValue(&keyValue, value); err != nil {
				if sectionName == Global {
					sectionName = globalName
				}
				return fmt.Errorf("ini: error decoding %q in section %q: %s",
					key, sectionName, err.Error())
			}

			return nil
		}
	}

	return nil
}

var seperators = []string{"", "_", "-", " "}

// PossibleNames generates possible names for a given name. It splits up the
// given name on upper case and underscores (see getNameParts) and then joins
// them using nothing (""), underscores, dashes and spaces (see seperators
// variable).
func possibleNames(name string) []string {
	nameParts := getNameParts(name)
	if len(nameParts) == 1 {
		return []string{name, strings.ToLower(name)}
	}

	var names []string
	for _, seperator := range seperators {
		var newName string
		for _, namePart := range nameParts {
			newName += namePart
			newName += seperator
		}
		newName = newName[:len(newName)-len(seperator)]

		names = append(names, strings.ToLower(newName))
		names = append(names, newName)
	}

	return names
}

// getNameParts splits a name on upper case and undersocres, it returns the
// split parts.
// todo: maybe split on first number?
func getNameParts(name string) []string {
	if name == "" {
		return []string{""}
	}

	var nameParts = []string{name[:1]}
	var i int
	for _, r := range name[1:] {
		if r == '_' || unicode.IsUpper(r) {
			nameParts = append(nameParts, string(r))
			i++
		} else {
			nameParts[i] += string(r)
		}
	}

	return nameParts
}

// GetConfigSectionsAlpha sort the sections alphabetically with the global
// section first.
func getConfigSectionsAlpha(c Config) []string {
	sections := make([]string, 0, len(c))
	for section := range c {
		if section != Global {
			sections = append(sections, section)
		}
	}
	sort.Strings(sections)
	return append([]string{Global}, sections...)
}
<commit_msg>Doc tags in Config.Decode<commit_after>// Copyright (C) 2015 Thomas de Zeeuw.
//
// Licensed under the MIT license that can be found in the LICENSE file.

// Package ini parses an ini formatted file. The parsed configuration can be
// decoded into a variable or used directly.
package ini

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"reflect"
	"sort"
	"strconv"
	"strings"
	"unicode"
)

// Global is the section name for key-values not under a section. It is used
// for retrieving key-value pairs in the "global" section, or not under any
// other section.
//
//	value := config[ini.Global]["key"]
//	value2, found := config[ini.Global]["key2"]
const Global = ""

// Name for the global section in errors.
const globalName = "global"

// Config holds all key-value pairs under sections. To retrieve a key-value
// pair you can use:
//
//	value := config["section"]["key"]
//	value2, found := config["section"]["key2"]
//
// The same as you would for a map. For retrieving key-value pairs not in any
// section, or the "global" section, you can use the `ini.Global` constant,
// like so:
//
//	value := config[ini.Global]["key"]
//	value2, found := config[ini.Global]["key2"]
type Config map[string]map[string]string

// String returns an ini formatted configuration, ready to be written to a file.
func (c *Config) String() string {
	return c.buffer().String()
}

// Bytes returns an ini formatted configuration, ready to be written to a file.
func (c *Config) Bytes() []byte {
	return c.buffer().Bytes()
}

// WriteTo writes the configuration to the writer in the ini format.
func (c *Config) WriteTo(w io.Writer) (int64, error) {
	return c.buffer().WriteTo(w)
}

// Buffer creates a `bytes.Buffer` with an ini formatted configuration.
func (c *Config) buffer() *bytes.Buffer {
	var result bytes.Buffer

	sections := getConfigSectionsAlpha(*c)
	for _, sectionName := range sections {
		if sectionName != Global {
			result.WriteString("[" + sectionName + "]\n")
		}

		section := (*c)[sectionName]
		keys := getMapsKeysAlpha(section)
		for _, key := range keys {
			value := strconv.Quote(section[key])
			key = strconv.Quote(key)
			result.WriteString(key + "=" + value + "\n")
		}
		result.WriteString("\n")
	}

	return &result
}

func getMapsKeysAlpha(m map[string]string) []string {
	keys := make([]string, 0, len(m))
	for key := range m {
		keys = append(keys, key)
	}
	sort.Strings(keys)
	return keys
}

type fieldCombo struct {
	value reflect.Value
	field reflect.StructField
}

// Decode decodes a configuration into a struct. Any properties to be set need
// to be public. Keys are renamed, whitespace is removed and keys start with a
// capaital, like so:
//
//	"my key" -> "MyKey"
//
// Tags are supported to define the key of a configuration. See below for a
// small example, for more examples see the tags example in the _examples
// directory.
//
//	struct {
//		AppName `ini:"name"`
//	}
//
// Slices are supported by using a comma separated list, like so:
//
//	"string1, string2" -> []string{"string1", "string2"}
//	"1, 2, 3" -> []int{1, 2, 3}
//
// Booleans are supported aswell:
//
//	"1, t, T, TRUE, true, True" -> true
//	"0, f, F, FALSE, false, False" -> false
//
// Time is supported with the following formats:
//
//	"2006-01-02", "2006-01-02 15:04", "2006-01-02 15:04:05", time.RFC3339,
//	time.RFC1123 and time.RFC822
//
// Duration is also supported, see `time.ParseDuration` for the documentation.
//
// Note: underneath Decode uses the reflect package which isn't great for
// performance, so use it with care.
func (c *Config) Decode(dst interface{}) error {
	valuePtr := reflect.ValueOf(dst)
	value := reflect.Indirect(valuePtr)

	// If it's not a pointer we can't change the original value and if it's not a
	// struct we can't set/change any keys on it, in either case we can't do
	// anything with the value.
	if valuePtr.Kind() != reflect.Ptr || value.Kind() != reflect.Struct {
		return errors.New("ini: Config.Decode requires a pointer to a struct")
	}

	dstType := value.Type()
	for i := value.NumField() - 1; i >= 0; i-- {
		field := value.Field(i)
		if !field.IsValid() || !field.CanSet() {
			continue
		}

		strField := dstType.Field(i)
		var fields []fieldCombo
		var sectionNames = []string{""}

		structFieldType := field.Type()
		if kind := field.Kind(); kind == reflect.Struct &&
			structFieldType != typeDuration && structFieldType != typeTime {
			sectionName := strField.Tag.Get("ini")
			if sectionName != "" {
				sectionNames[0] = sectionName
			} else {
				sectionNames = possibleNames(strField.Name)
			}

			for i := field.NumField() - 1; i >= 0; i-- {
				structField := field.Field(i)
				if !structField.IsValid() || !structField.CanSet() {
					continue
				}
				structFieldType := structFieldType.Field(i)
				fields = append(fields, fieldCombo{structField, structFieldType})
			}
		} else {
			fields = []fieldCombo{{field, strField}}
		}

		for _, combo := range fields {
			value := combo.value
			field := combo.field

			var keys []string
			if key := field.Tag.Get("ini"); key != "" {
				keys = []string{key}
			} else {
				keys = possibleNames(field.Name)
			}

			if err := c.trySetReflect(sectionNames, keys, value); err != nil {
				return err
			}
		}
	}

	return nil
}

// TrySetReflect tries the givens section and keys combination to get the value
// from the config and then sets the field if a value if found.
func (c *Config) trySetReflect(sectionNames []string, keys []string, keyValue reflect.Value) error {
	for _, sectionName := range sectionNames {
		section := (*c)[sectionName]
		if len(section) == 0 {
			continue
		}

		for _, key := range keys {
			value, ok := section[key]
			if !ok {
				continue
			}

			if err := setReflectValue(&keyValue, value); err != nil {
				if sectionName == Global {
					sectionName = globalName
				}
				return fmt.Errorf("ini: error decoding %q in section %q: %s",
					key, sectionName, err.Error())
			}

			return nil
		}
	}

	return nil
}

var seperators = []string{"", "_", "-", " "}

// PossibleNames generates possible names for a given name. It splits up the
// given name on upper case and underscores (see getNameParts) and then joins
// them using nothing (""), underscores, dashes and spaces (see seperators
// variable).
func possibleNames(name string) []string {
	nameParts := getNameParts(name)
	if len(nameParts) == 1 {
		return []string{name, strings.ToLower(name)}
	}

	var names []string
	for _, seperator := range seperators {
		var newName string
		for _, namePart := range nameParts {
			newName += namePart
			newName += seperator
		}
		newName = newName[:len(newName)-len(seperator)]

		names = append(names, strings.ToLower(newName))
		names = append(names, newName)
	}

	return names
}

// getNameParts splits a name on upper case and undersocres, it returns the
// split parts.
// todo: maybe split on first number?
func getNameParts(name string) []string {
	if name == "" {
		return []string{""}
	}

	var nameParts = []string{name[:1]}
	var i int
	for _, r := range name[1:] {
		if r == '_' || unicode.IsUpper(r) {
			nameParts = append(nameParts, string(r))
			i++
		} else {
			nameParts[i] += string(r)
		}
	}

	return nameParts
}

// GetConfigSectionsAlpha sort the sections alphabetically with the global
// section first.
func getConfigSectionsAlpha(c Config) []string {
	sections := make([]string, 0, len(c))
	for section := range c {
		if section != Global {
			sections = append(sections, section)
		}
	}
	sort.Strings(sections)
	return append([]string{Global}, sections...)
}
<|endoftext|>


<commit_before>package fastjet

import (
	"math"

	"github.com/go-hep/fmom"
)

// // Used to protect against parton-level events where pt can be zero
// // for some partons, giving rapidity=infinity. KtJet fails in those cases.
// const (
// 	MaxRap = 1e5
// )

// UserInfo holds extra user information in a Jet
type UserInfo interface{}

// Jet holds minimal information of use for jet-clustering routines
type Jet struct {
	fmom.PxPyPzE

	UserInfo  UserInfo // holds extra user information for this Jet
	hidx      int      // cluster sequence history index
	structure JetStructure
}

func NewJet(px, py, pz, e float64) Jet {
	return Jet{
		PxPyPzE: fmom.NewPxPyPzE(px, py, pz, e),
		hidx:    -1,
	}
}

func (jet *Jet) Pt2() float64 {
	pt := jet.Pt()
	return pt * pt
}

func (jet *Jet) Rapidity() float64 {
	return 0.5 * math.Log((jet.E()+jet.Pz())/(jet.E()-jet.Pz()))
	/*
		var rap float64
		if jet.E() == math.Abs(jet.Pz()) && jet.Pt2() == 0 {
			rap = MaxRap + math.Abs(jet.Pz())
		} else {
			m := jet.M()
			m2 := math.Max(0, m*m) // effective mass - force non-tachyonic mass
			e := jet.E() + math.Abs(jet.Pz())
			rap = 0.5 * math.Log((jet.Pt2()+m2)/(e*e))
		}

		if jet.Pz() > 0 {
			rap = -rap
		}
		return rap
	*/
}

func (jet *Jet) Constituents() []Jet {
	// FIXME
	return nil
}

// Distance returns the squared cylinder (rapidity-phi) distance between 2 jets
func Distance(j1, j2 *Jet) float64 {
	dphi := math.Abs(j1.Phi() - j2.Phi())
	if dphi > math.Pi {
		dphi = 2*math.Phi - dphi
	}
	drap := j1.Rapidity() - j2.Rapidity()
	return dphi*dphi + drap*drap
}
<commit_msg>jet: add handling of constituents<commit_after>package fastjet

import (
	"math"

	"github.com/go-hep/fmom"
)

// // Used to protect against parton-level events where pt can be zero
// // for some partons, giving rapidity=infinity. KtJet fails in those cases.
// const (
// 	MaxRap = 1e5
// )

// UserInfo holds extra user information in a Jet
type UserInfo interface{}

// Jet holds minimal information of use for jet-clustering routines
type Jet struct {
	fmom.PxPyPzE

	UserInfo  UserInfo // holds extra user information for this Jet
	hidx      int      // cluster sequence history index
	structure JetStructure
}

func NewJet(px, py, pz, e float64) Jet {
	return Jet{
		PxPyPzE: fmom.NewPxPyPzE(px, py, pz, e),
		hidx:    -1,
	}
}

func (jet *Jet) Pt2() float64 {
	pt := jet.Pt()
	return pt * pt
}

func (jet *Jet) Rapidity() float64 {
	return 0.5 * math.Log((jet.E()+jet.Pz())/(jet.E()-jet.Pz()))
	/*
		var rap float64
		if jet.E() == math.Abs(jet.Pz()) && jet.Pt2() == 0 {
			rap = MaxRap + math.Abs(jet.Pz())
		} else {
			m := jet.M()
			m2 := math.Max(0, m*m) // effective mass - force non-tachyonic mass
			e := jet.E() + math.Abs(jet.Pz())
			rap = 0.5 * math.Log((jet.Pt2()+m2)/(e*e))
		}

		if jet.Pz() > 0 {
			rap = -rap
		}
		return rap
	*/
}

// Constituents returns the list of constituents for this jet.
func (jet *Jet) Constituents() []Jet {
	subjets, err := jet.structure.Constituents(jet)
	if err != nil {
		panic(err)
	}
	return subjets
}

// Distance returns the squared cylinder (rapidity-phi) distance between 2 jets
func Distance(j1, j2 *Jet) float64 {
	dphi := math.Abs(j1.Phi() - j2.Phi())
	if dphi > math.Pi {
		dphi = 2*math.Phi - dphi
	}
	drap := j1.Rapidity() - j2.Rapidity()
	return dphi*dphi + drap*drap
}
<|endoftext|>