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

/*
Package signal implements access to incoming signals.

Signals are primarily used on Unix-like systems. For the use of this
package on Windows and Plan 9, see below.

# Types of signals

The signals SIGKILL and SIGSTOP may not be caught by a program, and
therefore cannot be affected by this package.

Synchronous signals are signals triggered by errors in program
execution: SIGBUS, SIGFPE, and SIGSEGV. These are only considered
synchronous when caused by program execution, not when sent using
os.Process.Kill or the kill program or some similar mechanism. In
general, except as discussed below, Go programs will convert a
synchronous signal into a run-time panic.

The remaining signals are asynchronous signals. They are not
triggered by program errors, but are instead sent from the kernel or
from some other program.

Of the asynchronous signals, the SIGHUP signal is sent when a program
loses its controlling terminal. The SIGINT signal is sent when the
user at the controlling terminal presses the interrupt character,
which by default is ^C (Control-C). The SIGQUIT signal is sent when
the user at the controlling terminal presses the quit character, which
by default is ^\ (Control-Backslash). In general you can cause a
program to simply exit by pressing ^C, and you can cause it to exit
with a stack dump by pressing ^\.

# Default behavior of signals in Go programs

By default, a synchronous signal is converted into a run-time panic. A
SIGHUP, SIGINT, or SIGTERM signal causes the program to exit. A
SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGSTKFLT, SIGEMT, or SIGSYS signal
causes the program to exit with a stack dump. A SIGTSTP, SIGTTIN, or
SIGTTOU signal gets the system default behavior (these signals are
used by the shell for job control). The SIGPROF signal is handled
directly by the Go runtime to implement runtime.CPUProfile. Other
signals will be caught but no action will be taken.

If the Go program is started with either SIGHUP or SIGINT ignored
(signal handler set to SIG_IGN), they will remain ignored.

If the Go program is started with a non-empty signal mask, that will
generally be honored. However, some signals are explicitly unblocked:
the synchronous signals, SIGILL, SIGTRAP, SIGSTKFLT, SIGCHLD, SIGPROF,
and, on Linux, signals 32 (SIGCANCEL) and 33 (SIGSETXID)
(SIGCANCEL and SIGSETXID are used internally by glibc). Subprocesses
started by os.Exec, or by the os/exec package, will inherit the
modified signal mask.

# Changing the behavior of signals in Go programs

The functions in this package allow a program to change the way Go
programs handle signals.

Notify disables the default behavior for a given set of asynchronous
signals and instead delivers them over one or more registered
channels. Specifically, it applies to the signals SIGHUP, SIGINT,
SIGQUIT, SIGABRT, and SIGTERM. It also applies to the job control
signals SIGTSTP, SIGTTIN, and SIGTTOU, in which case the system
default behavior does not occur. It also applies to some signals that
otherwise cause no action: SIGUSR1, SIGUSR2, SIGPIPE, SIGALRM,
SIGCHLD, SIGCONT, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGWINCH,
SIGIO, SIGPWR, SIGSYS, SIGINFO, SIGTHR, SIGWAITING, SIGLWP, SIGFREEZE,
SIGTHAW, SIGLOST, SIGXRES, SIGJVM1, SIGJVM2, and any real time signals
used on the system. Note that not all of these signals are available
on all systems.

If the program was started with SIGHUP or SIGINT ignored, and Notify
is called for either signal, a signal handler will be installed for
that signal and it will no longer be ignored. If, later, Reset or
Ignore is called for that signal, or Stop is called on all channels
passed to Notify for that signal, the signal will once again be
ignored. Reset will restore the system default behavior for the
signal, while Ignore will cause the system to ignore the signal
entirely.

If the program is started with a non-empty signal mask, some signals
will be explicitly unblocked as described above. If Notify is called
for a blocked signal, it will be unblocked. If, later, Reset is
called for that signal, or Stop is called on all channels passed to
Notify for that signal, the signal will once again be blocked.

# SIGPIPE

When a Go program writes to a broken pipe, the kernel will raise a
SIGPIPE signal.

If the program has not called Notify to receive SIGPIPE signals, then
the behavior depends on the file descriptor number. A write to a
broken pipe on file descriptors 1 or 2 (standard output or standard
error) will cause the program to exit with a SIGPIPE signal. A write
to a broken pipe on some other file descriptor will take no action on
the SIGPIPE signal, and the write will fail with an EPIPE error.

If the program has called Notify to receive SIGPIPE signals, the file
descriptor number does not matter. The SIGPIPE signal will be
delivered to the Notify channel, and the write will fail with an EPIPE
error.

This means that, by default, command line programs will behave like
typical Unix command line programs, while other programs will not
crash with SIGPIPE when writing to a closed network connection.

# Go programs that use cgo or SWIG

In a Go program that includes non-Go code, typically C/C++ code
accessed using cgo or SWIG, Go's startup code normally runs first. It
configures the signal handlers as expected by the Go runtime, before
the non-Go startup code runs. If the non-Go startup code wishes to
install its own signal handlers, it must take certain steps to keep Go
working well. This section documents those steps and the overall
effect changes to signal handler settings by the non-Go code can have
on Go programs. In rare cases, the non-Go code may run before the Go
code, in which case the next section also applies.

If the non-Go code called by the Go program does not change any signal
handlers or masks, then the behavior is the same as for a pure Go
program.

If the non-Go code installs any signal handlers, it must use the
SA_ONSTACK flag with sigaction. Failing to do so is likely to cause
the program to crash if the signal is received. Go programs routinely
run with a limited stack, and therefore set up an alternate signal
stack.

If the non-Go code installs a signal handler for any of the
synchronous signals (SIGBUS, SIGFPE, SIGSEGV), then it should record
the existing Go signal handler. If those signals occur while
executing Go code, it should invoke the Go signal handler (whether the
signal occurs while executing Go code can be determined by looking at
the PC passed to the signal handler). Otherwise some Go run-time
panics will not occur as expected.

If the non-Go code installs a signal handler for any of the
asynchronous signals, it may invoke the Go signal handler or not as it
chooses. Naturally, if it does not invoke the Go signal handler, the
Go behavior described above will not occur. This can be an issue with
the SIGPROF signal in particular.

The non-Go code should not change the signal mask on any threads
created by the Go runtime. If the non-Go code starts new threads of
its own, it may set the signal mask as it pleases.

If the non-Go code starts a new thread, changes the signal mask, and
then invokes a Go function in that thread, the Go runtime will
automatically unblock certain signals: the synchronous signals,
SIGILL, SIGTRAP, SIGSTKFLT, SIGCHLD, SIGPROF, SIGCANCEL, and
SIGSETXID. When the Go function returns, the non-Go signal mask will
be restored.

If the Go signal handler is invoked on a non-Go thread not running Go
code, the handler generally forwards the signal to the non-Go code, as
follows. If the signal is SIGPROF, the Go handler does
nothing. Otherwise, the Go handler removes itself, unblocks the
signal, and raises it again, to invoke any non-Go handler or default
system handler. If the program does not exit, the Go handler then
reinstalls itself and continues execution of the program.

# Non-Go programs that call Go code

When Go code is built with options like -buildmode=c-shared, it will
be run as part of an existing non-Go program. The non-Go code may
have already installed signal handlers when the Go code starts (that
may also happen in unusual cases when using cgo or SWIG; in that case,
the discussion here applies).  For -buildmode=c-archive the Go runtime
will initialize signals at global constructor time.  For
-buildmode=c-shared the Go runtime will initialize signals when the
shared library is loaded.

If the Go runtime sees an existing signal handler for the SIGCANCEL or
SIGSETXID signals (which are used only on Linux), it will turn on
the SA_ONSTACK flag and otherwise keep the signal handler.

For the synchronous signals and SIGPIPE, the Go runtime will install a
signal handler. It will save any existing signal handler. If a
synchronous signal arrives while executing non-Go code, the Go runtime
will invoke the existing signal handler instead of the Go signal
handler.

Go code built with -buildmode=c-archive or -buildmode=c-shared will
not install any other signal handlers by default. If there is an
existing signal handler, the Go runtime will turn on the SA_ONSTACK
flag and otherwise keep the signal handler. If Notify is called for an
asynchronous signal, a Go signal handler will be installed for that
signal. If, later, Reset is called for that signal, the original
handling for that signal will be reinstalled, restoring the non-Go
signal handler if any.

Go code built without -buildmode=c-archive or -buildmode=c-shared will
install a signal handler for the asynchronous signals listed above,
and save any existing signal handler. If a signal is delivered to a
non-Go thread, it will act as described above, except that if there is
an existing non-Go signal handler, that handler will be installed
before raising the signal.

# Windows

On Windows a ^C (Control-C) or ^BREAK (Control-Break) normally cause
the program to exit. If Notify is called for os.Interrupt, ^C or ^BREAK
will cause os.Interrupt to be sent on the channel, and the program will
not exit. If Reset is called, or Stop is called on all channels passed
to Notify, then the default behavior will be restored.

Additionally, if Notify is called, and Windows sends CTRL_CLOSE_EVENT,
CTRL_LOGOFF_EVENT or CTRL_SHUTDOWN_EVENT to the process, Notify will
return syscall.SIGTERM. Unlike Control-C and Control-Break, Notify does
not change process behavior when either CTRL_CLOSE_EVENT,
CTRL_LOGOFF_EVENT or CTRL_SHUTDOWN_EVENT is received - the process will
still get terminated unless it exits. But receiving syscall.SIGTERM will
give the process an opportunity to clean up before termination.

# Plan 9

On Plan 9, signals have type syscall.Note, which is a string. Calling
Notify with a syscall.Note will cause that value to be sent on the
channel when that string is posted as a note.
*/
package signal
<commit_msg>os/signal: document behavior of SIGPIPE on non-Go thread<commit_after>// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
Package signal implements access to incoming signals.

Signals are primarily used on Unix-like systems. For the use of this
package on Windows and Plan 9, see below.

# Types of signals

The signals SIGKILL and SIGSTOP may not be caught by a program, and
therefore cannot be affected by this package.

Synchronous signals are signals triggered by errors in program
execution: SIGBUS, SIGFPE, and SIGSEGV. These are only considered
synchronous when caused by program execution, not when sent using
os.Process.Kill or the kill program or some similar mechanism. In
general, except as discussed below, Go programs will convert a
synchronous signal into a run-time panic.

The remaining signals are asynchronous signals. They are not
triggered by program errors, but are instead sent from the kernel or
from some other program.

Of the asynchronous signals, the SIGHUP signal is sent when a program
loses its controlling terminal. The SIGINT signal is sent when the
user at the controlling terminal presses the interrupt character,
which by default is ^C (Control-C). The SIGQUIT signal is sent when
the user at the controlling terminal presses the quit character, which
by default is ^\ (Control-Backslash). In general you can cause a
program to simply exit by pressing ^C, and you can cause it to exit
with a stack dump by pressing ^\.

# Default behavior of signals in Go programs

By default, a synchronous signal is converted into a run-time panic. A
SIGHUP, SIGINT, or SIGTERM signal causes the program to exit. A
SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGSTKFLT, SIGEMT, or SIGSYS signal
causes the program to exit with a stack dump. A SIGTSTP, SIGTTIN, or
SIGTTOU signal gets the system default behavior (these signals are
used by the shell for job control). The SIGPROF signal is handled
directly by the Go runtime to implement runtime.CPUProfile. Other
signals will be caught but no action will be taken.

If the Go program is started with either SIGHUP or SIGINT ignored
(signal handler set to SIG_IGN), they will remain ignored.

If the Go program is started with a non-empty signal mask, that will
generally be honored. However, some signals are explicitly unblocked:
the synchronous signals, SIGILL, SIGTRAP, SIGSTKFLT, SIGCHLD, SIGPROF,
and, on Linux, signals 32 (SIGCANCEL) and 33 (SIGSETXID)
(SIGCANCEL and SIGSETXID are used internally by glibc). Subprocesses
started by os.Exec, or by the os/exec package, will inherit the
modified signal mask.

# Changing the behavior of signals in Go programs

The functions in this package allow a program to change the way Go
programs handle signals.

Notify disables the default behavior for a given set of asynchronous
signals and instead delivers them over one or more registered
channels. Specifically, it applies to the signals SIGHUP, SIGINT,
SIGQUIT, SIGABRT, and SIGTERM. It also applies to the job control
signals SIGTSTP, SIGTTIN, and SIGTTOU, in which case the system
default behavior does not occur. It also applies to some signals that
otherwise cause no action: SIGUSR1, SIGUSR2, SIGPIPE, SIGALRM,
SIGCHLD, SIGCONT, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGWINCH,
SIGIO, SIGPWR, SIGSYS, SIGINFO, SIGTHR, SIGWAITING, SIGLWP, SIGFREEZE,
SIGTHAW, SIGLOST, SIGXRES, SIGJVM1, SIGJVM2, and any real time signals
used on the system. Note that not all of these signals are available
on all systems.

If the program was started with SIGHUP or SIGINT ignored, and Notify
is called for either signal, a signal handler will be installed for
that signal and it will no longer be ignored. If, later, Reset or
Ignore is called for that signal, or Stop is called on all channels
passed to Notify for that signal, the signal will once again be
ignored. Reset will restore the system default behavior for the
signal, while Ignore will cause the system to ignore the signal
entirely.

If the program is started with a non-empty signal mask, some signals
will be explicitly unblocked as described above. If Notify is called
for a blocked signal, it will be unblocked. If, later, Reset is
called for that signal, or Stop is called on all channels passed to
Notify for that signal, the signal will once again be blocked.

# SIGPIPE

When a Go program writes to a broken pipe, the kernel will raise a
SIGPIPE signal.

If the program has not called Notify to receive SIGPIPE signals, then
the behavior depends on the file descriptor number. A write to a
broken pipe on file descriptors 1 or 2 (standard output or standard
error) will cause the program to exit with a SIGPIPE signal. A write
to a broken pipe on some other file descriptor will take no action on
the SIGPIPE signal, and the write will fail with an EPIPE error.

If the program has called Notify to receive SIGPIPE signals, the file
descriptor number does not matter. The SIGPIPE signal will be
delivered to the Notify channel, and the write will fail with an EPIPE
error.

This means that, by default, command line programs will behave like
typical Unix command line programs, while other programs will not
crash with SIGPIPE when writing to a closed network connection.

# Go programs that use cgo or SWIG

In a Go program that includes non-Go code, typically C/C++ code
accessed using cgo or SWIG, Go's startup code normally runs first. It
configures the signal handlers as expected by the Go runtime, before
the non-Go startup code runs. If the non-Go startup code wishes to
install its own signal handlers, it must take certain steps to keep Go
working well. This section documents those steps and the overall
effect changes to signal handler settings by the non-Go code can have
on Go programs. In rare cases, the non-Go code may run before the Go
code, in which case the next section also applies.

If the non-Go code called by the Go program does not change any signal
handlers or masks, then the behavior is the same as for a pure Go
program.

If the non-Go code installs any signal handlers, it must use the
SA_ONSTACK flag with sigaction. Failing to do so is likely to cause
the program to crash if the signal is received. Go programs routinely
run with a limited stack, and therefore set up an alternate signal
stack.

If the non-Go code installs a signal handler for any of the
synchronous signals (SIGBUS, SIGFPE, SIGSEGV), then it should record
the existing Go signal handler. If those signals occur while
executing Go code, it should invoke the Go signal handler (whether the
signal occurs while executing Go code can be determined by looking at
the PC passed to the signal handler). Otherwise some Go run-time
panics will not occur as expected.

If the non-Go code installs a signal handler for any of the
asynchronous signals, it may invoke the Go signal handler or not as it
chooses. Naturally, if it does not invoke the Go signal handler, the
Go behavior described above will not occur. This can be an issue with
the SIGPROF signal in particular.

The non-Go code should not change the signal mask on any threads
created by the Go runtime. If the non-Go code starts new threads of
its own, it may set the signal mask as it pleases.

If the non-Go code starts a new thread, changes the signal mask, and
then invokes a Go function in that thread, the Go runtime will
automatically unblock certain signals: the synchronous signals,
SIGILL, SIGTRAP, SIGSTKFLT, SIGCHLD, SIGPROF, SIGCANCEL, and
SIGSETXID. When the Go function returns, the non-Go signal mask will
be restored.

If the Go signal handler is invoked on a non-Go thread not running Go
code, the handler generally forwards the signal to the non-Go code, as
follows. If the signal is SIGPROF, the Go handler does
nothing. Otherwise, the Go handler removes itself, unblocks the
signal, and raises it again, to invoke any non-Go handler or default
system handler. If the program does not exit, the Go handler then
reinstalls itself and continues execution of the program.

If a SIGPIPE signal is received, the Go program will invoke the
special handling described above if the SIGPIPE is received on a Go
thread.  If the SIGPIPE is received on a non-Go thread the signal will
be forwarded to the non-Go handler, if any; if there is none the
default system handler will cause the program to terminate.

# Non-Go programs that call Go code

When Go code is built with options like -buildmode=c-shared, it will
be run as part of an existing non-Go program. The non-Go code may
have already installed signal handlers when the Go code starts (that
may also happen in unusual cases when using cgo or SWIG; in that case,
the discussion here applies).  For -buildmode=c-archive the Go runtime
will initialize signals at global constructor time.  For
-buildmode=c-shared the Go runtime will initialize signals when the
shared library is loaded.

If the Go runtime sees an existing signal handler for the SIGCANCEL or
SIGSETXID signals (which are used only on Linux), it will turn on
the SA_ONSTACK flag and otherwise keep the signal handler.

For the synchronous signals and SIGPIPE, the Go runtime will install a
signal handler. It will save any existing signal handler. If a
synchronous signal arrives while executing non-Go code, the Go runtime
will invoke the existing signal handler instead of the Go signal
handler.

Go code built with -buildmode=c-archive or -buildmode=c-shared will
not install any other signal handlers by default. If there is an
existing signal handler, the Go runtime will turn on the SA_ONSTACK
flag and otherwise keep the signal handler. If Notify is called for an
asynchronous signal, a Go signal handler will be installed for that
signal. If, later, Reset is called for that signal, the original
handling for that signal will be reinstalled, restoring the non-Go
signal handler if any.

Go code built without -buildmode=c-archive or -buildmode=c-shared will
install a signal handler for the asynchronous signals listed above,
and save any existing signal handler. If a signal is delivered to a
non-Go thread, it will act as described above, except that if there is
an existing non-Go signal handler, that handler will be installed
before raising the signal.

# Windows

On Windows a ^C (Control-C) or ^BREAK (Control-Break) normally cause
the program to exit. If Notify is called for os.Interrupt, ^C or ^BREAK
will cause os.Interrupt to be sent on the channel, and the program will
not exit. If Reset is called, or Stop is called on all channels passed
to Notify, then the default behavior will be restored.

Additionally, if Notify is called, and Windows sends CTRL_CLOSE_EVENT,
CTRL_LOGOFF_EVENT or CTRL_SHUTDOWN_EVENT to the process, Notify will
return syscall.SIGTERM. Unlike Control-C and Control-Break, Notify does
not change process behavior when either CTRL_CLOSE_EVENT,
CTRL_LOGOFF_EVENT or CTRL_SHUTDOWN_EVENT is received - the process will
still get terminated unless it exits. But receiving syscall.SIGTERM will
give the process an opportunity to clean up before termination.

# Plan 9

On Plan 9, signals have type syscall.Note, which is a string. Calling
Notify with a syscall.Note will cause that value to be sent on the
channel when that string is posted as a note.
*/
package signal
<|endoftext|>


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

package math

// The original C code, the long comment, and the constants
// below were from http://netlib.sandia.gov/cephes/cmath/sin.c,
// available from http://www.netlib.org/cephes/cmath.tgz.
// The go code is a simplified version of the original C.
//      tanh.c
//
//      Hyperbolic tangent
//
// SYNOPSIS:
//
// double x, y, tanh();
//
// y = tanh( x );
//
// DESCRIPTION:
//
// Returns hyperbolic tangent of argument in the range MINLOG to MAXLOG.
//      MAXLOG = 8.8029691931113054295988e+01 = log(2**127)
//      MINLOG = -8.872283911167299960540e+01 = log(2**-128)
//
// A rational function is used for |x| < 0.625.  The form
// x + x**3 P(x)/Q(x) of Cody & Waite is employed.
// Otherwise,
//      tanh(x) = sinh(x)/cosh(x) = 1  -  2/(exp(2x) + 1).
//
// ACCURACY:
//
//                      Relative error:
// arithmetic   domain     # trials      peak         rms
//    IEEE      -2,2        30000       2.5e-16     5.8e-17
//
// Cephes Math Library Release 2.8:  June, 2000
// Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier
//
// The readme file at http://netlib.sandia.gov/cephes/ says:
//    Some software in this archive may be from the book _Methods and
// Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster
// International, 1989) or from the Cephes Mathematical Library, a
// commercial product. In either event, it is copyrighted by the author.
// What you see here may be used freely but it comes with no support or
// guarantee.
//
//   The two known misprints in the book are repaired here in the
// source listings for the gamma function and the incomplete beta
// integral.
//
//   Stephen L. Moshier
//   moshier@na-net.ornl.gov
//

var tanhP = [...]float64{
	-9.64399179425052238628E-1,
	-9.92877231001918586564E1,
	-1.61468768441708447952E3,
}
var tanhQ = [...]float64{
	1.12811678491632931402E2,
	2.23548839060100448583E3,
	4.84406305325125486048E3,
}

// Tanh computes the hyperbolic tangent of x.
//
// Special cases are:
//	Tanh(±0) = ±0
//	Tanh(±Inf) = ±1
//	Tanh(NaN) = NaN
func Tanh(x float64) float64 {
	const MAXLOG = 8.8029691931113054295988e+01 // log(2**127)
	z := Abs(x)
	switch {
	case z > 0.5*MAXLOG:
		if x < 0 {
			return -1
		}
		return 1
	case z >= 0.625:
		s := Exp(2 * z)
		z = 1 - 2/(s+1)
		if x < 0 {
			z = -z
		}
	default:
		if x == 0 {
			return x
		}
		s := x * x
		z = x + x*s*((tanhP[0]*s+tanhP[1])*s+tanhP[2])/(((s+tanhQ[0])*s+tanhQ[1])*s+tanhQ[2])
	}
	return z
}
<commit_msg>math: modify a comment to the convention format.<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package math

// The original C code, the long comment, and the constants
// below were from http://netlib.sandia.gov/cephes/cmath/sin.c,
// available from http://www.netlib.org/cephes/cmath.tgz.
// The go code is a simplified version of the original C.
//      tanh.c
//
//      Hyperbolic tangent
//
// SYNOPSIS:
//
// double x, y, tanh();
//
// y = tanh( x );
//
// DESCRIPTION:
//
// Returns hyperbolic tangent of argument in the range MINLOG to MAXLOG.
//      MAXLOG = 8.8029691931113054295988e+01 = log(2**127)
//      MINLOG = -8.872283911167299960540e+01 = log(2**-128)
//
// A rational function is used for |x| < 0.625.  The form
// x + x**3 P(x)/Q(x) of Cody & Waite is employed.
// Otherwise,
//      tanh(x) = sinh(x)/cosh(x) = 1  -  2/(exp(2x) + 1).
//
// ACCURACY:
//
//                      Relative error:
// arithmetic   domain     # trials      peak         rms
//    IEEE      -2,2        30000       2.5e-16     5.8e-17
//
// Cephes Math Library Release 2.8:  June, 2000
// Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier
//
// The readme file at http://netlib.sandia.gov/cephes/ says:
//    Some software in this archive may be from the book _Methods and
// Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster
// International, 1989) or from the Cephes Mathematical Library, a
// commercial product. In either event, it is copyrighted by the author.
// What you see here may be used freely but it comes with no support or
// guarantee.
//
//   The two known misprints in the book are repaired here in the
// source listings for the gamma function and the incomplete beta
// integral.
//
//   Stephen L. Moshier
//   moshier@na-net.ornl.gov
//

var tanhP = [...]float64{
	-9.64399179425052238628E-1,
	-9.92877231001918586564E1,
	-1.61468768441708447952E3,
}
var tanhQ = [...]float64{
	1.12811678491632931402E2,
	2.23548839060100448583E3,
	4.84406305325125486048E3,
}

// Tanh returns the hyperbolic tangent of x.
//
// Special cases are:
//	Tanh(±0) = ±0
//	Tanh(±Inf) = ±1
//	Tanh(NaN) = NaN
func Tanh(x float64) float64 {
	const MAXLOG = 8.8029691931113054295988e+01 // log(2**127)
	z := Abs(x)
	switch {
	case z > 0.5*MAXLOG:
		if x < 0 {
			return -1
		}
		return 1
	case z >= 0.625:
		s := Exp(2 * z)
		z = 1 - 2/(s+1)
		if x < 0 {
			z = -z
		}
	default:
		if x == 0 {
			return x
		}
		s := x * x
		z = x + x*s*((tanhP[0]*s+tanhP[1])*s+tanhP[2])/(((s+tanhQ[0])*s+tanhQ[1])*s+tanhQ[2])
	}
	return z
}
<|endoftext|>


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

package rpc

/*
	Some HTML presented at http://machine:port/debug/rpc
	Lists services, their methods, and some statistics, still rudimentary.
*/

import (
	"fmt"
	"http"
	"sort"
	"template"
)

const debugText = `

	<title>Services</title>
	{.repeated section @}

	Service {Name}

		Method	Calls
		{.repeated section Method}

			{Name}({Type.ArgType}, {Type.ReplyType}) os.Error
			{Type.NumCalls}

		{.end}

	{.end}

	`

var debug = template.MustParse(debugText, nil)

type debugMethod struct {
	Type *methodType
	Name string
}

type methodArray []debugMethod

type debugService struct {
	Service *service
	Name    string
	Method  methodArray
}

type serviceArray []debugService

func (s serviceArray) Len() int           { return len(s) }
func (s serviceArray) Less(i, j int) bool { return s[i].Name < s[j].Name }
func (s serviceArray) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }

func (m methodArray) Len() int           { return len(m) }
func (m methodArray) Less(i, j int) bool { return m[i].Name < m[j].Name }
func (m methodArray) Swap(i, j int)      { m[i], m[j] = m[j], m[i] }

type debugHTTP struct {
	*Server
}

// Runs at /debug/rpc
func (server debugHTTP) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	// Build a sorted version of the data.
	var services = make(serviceArray, len(server.serviceMap))
	i := 0
	server.Lock()
	for sname, service := range server.serviceMap {
		services[i] = debugService{service, sname, make(methodArray, len(service.method))}
		j := 0
		for mname, method := range service.method {
			services[i].Method[j] = debugMethod{method, mname}
			j++
		}
		sort.Sort(services[i].Method)
		i++
	}
	server.Unlock()
	sort.Sort(services)
	err := debug.Execute(w, services)
	if err != nil {
		fmt.Fprintln(w, "rpc: error executing template:", err.String())
	}
}
<commit_msg>rpc: convert /debug/rpc handler to exp/template<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package rpc

/*
	Some HTML presented at http://machine:port/debug/rpc
	Lists services, their methods, and some statistics, still rudimentary.
*/

import (
	"exp/template"
	"fmt"
	"http"
	"sort"
)

const debugText = `

	<title>Services</title>
	{{range .}}

	Service {{.Name}}

		Method	Calls
		{{range .Method}}

			{{.Name}}({{.Type.ArgType}}, {{.Type.ReplyType}}) os.Error
			{{.Type.NumCalls}}

		{{end}}

	{{end}}

	`

var debug = template.New("RPC debug").MustParse(debugText)

type debugMethod struct {
	Type *methodType
	Name string
}

type methodArray []debugMethod

type debugService struct {
	Service *service
	Name    string
	Method  methodArray
}

type serviceArray []debugService

func (s serviceArray) Len() int           { return len(s) }
func (s serviceArray) Less(i, j int) bool { return s[i].Name < s[j].Name }
func (s serviceArray) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }

func (m methodArray) Len() int           { return len(m) }
func (m methodArray) Less(i, j int) bool { return m[i].Name < m[j].Name }
func (m methodArray) Swap(i, j int)      { m[i], m[j] = m[j], m[i] }

type debugHTTP struct {
	*Server
}

// Runs at /debug/rpc
func (server debugHTTP) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	// Build a sorted version of the data.
	var services = make(serviceArray, len(server.serviceMap))
	i := 0
	server.Lock()
	for sname, service := range server.serviceMap {
		services[i] = debugService{service, sname, make(methodArray, len(service.method))}
		j := 0
		for mname, method := range service.method {
			services[i].Method[j] = debugMethod{method, mname}
			j++
		}
		sort.Sort(services[i].Method)
		i++
	}
	server.Unlock()
	sort.Sort(services)
	err := debug.Execute(w, services)
	if err != nil {
		fmt.Fprintln(w, "rpc: error executing template:", err.String())
	}
}
<|endoftext|>


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

// The sort package provides primitives for sorting arrays
// and user-defined collections.
package sort

// SortInterface is the interface that a type, typically a collection,
// must implement for its contents to be sorted in increasing order.
// Its methods require that the elements of the collection be enumerated
// by an integer index.
type SortInterface interface {
	// Len is the number of elements in the collection.
	Len() int;
	// Less returns whether the element with index i is should sort
	// before the element with index j.
	// TODO(r): should this method be renamed Before?
	Less(i, j int) bool;
	// Swap swaps the elements with indexes i and j.
	Swap(i, j int);
}

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

// Insertion sort
func insertionSort(data SortInterface, a, b int) {
	for i := a+1; i < b; i++ {
		for j := i; j > a && data.Less(j, j-1); j-- {
			data.Swap(j, j-1);
		}
	}
}

// Quicksort, following Bentley and McIlroy,
// ``Engineering a Sort Function,'' SP&E November 1993.

// Move the median of the three values data[a], data[b], data[c] into data[a].
func medianOfThree(data SortInterface, a, b, c int) {
	m0 := b;
	m1 := a;
	m2 := c;
	// bubble sort on 3 elements
	if data.Less(m1, m0) { data.Swap(m1, m0); }
	if data.Less(m2, m1) { data.Swap(m2, m1); }
	if data.Less(m1, m0) { data.Swap(m1, m0); }
	// now data[m0] <= data[m1] <= data[m2]
}

func swapRange(data SortInterface, a, b, n int) {
	for i := 0; i < n; i++ {
		data.Swap(a+i, b+i);
	}
}

func doPivot(data SortInterface, lo, hi int) (midlo, midhi int) {
	m := (lo+hi)/2;
	if hi - lo > 40 {
		// Tukey's ``Ninther,'' median of three medians of three.
		s := (hi - lo) / 8;
		medianOfThree(data, lo, lo+s, lo+2*s);
		medianOfThree(data, m, m-s, m+s);
		medianOfThree(data, hi-1, hi-1-s, hi-1-2*s);
	}
	medianOfThree(data, lo, m, hi-1);

	// Invariants are:
	//	data[lo] = pivot (set up by ChoosePivot)
	//	data[lo <= i < a] = pivot
	//	data[a <= i < b] < pivot
	//	data[b <= i < c] is unexamined
	//	data[c <= i < d] > pivot
	//	data[d <= i < hi] = pivot
	//
	// Once b meets c, can swap the "= pivot" sections
	// into the middle of the array.
	pivot := lo;
	a, b, c, d := lo+1, lo+1, hi, hi;
	for b < c {
		if data.Less(b, pivot) {	// data[b] < pivot
			b++;
			continue;
		}
		if !data.Less(pivot, b) {	// data[b] = pivot
			data.Swap(a, b);
			a++;
			b++;
			continue;
		}
		if data.Less(pivot, c-1) {	// data[c-1] > pivot
			c--;
			continue;
		}
		if !data.Less(c-1, pivot) {	// data[c-1] = pivot
			data.Swap(c-1, d-1);
			c--;
			d--;
			continue;
		}
		// data[b] > pivot; data[c-1] < pivot
		data.Swap(b, c-1);
		b++;
		c--;
	}

	n := min(b-a, a-lo);
	swapRange(data, lo, b-n, n);

	n = min(hi-d, d-c);
	swapRange(data, c, hi-n, n);

	return lo+b-a, hi-(d-c);
}

func quickSort(data SortInterface, a, b int) {
	if b - a > 7 {
		mlo, mhi := doPivot(data, a, b);
		quickSort(data, a, mlo);
		quickSort(data, mhi, b);
	} else if b - a > 1 {
		insertionSort(data, a, b);
	}
}

func Sort(data SortInterface) {
	quickSort(data, 0, data.Len());
}

func IsSorted(data SortInterface) bool {
	n := data.Len();
	for i := n - 1; i > 0; i-- {
		if data.Less(i, i - 1) {
			return false;
		}
	}
	return true;
}

// Convenience types for common cases

// IntArray attaches the methods of SortInterface to []int, sorting in increasing order.
type IntArray []int

func (p IntArray) Len() int            { return len(p); }
func (p IntArray) Less(i, j int) bool  { return p[i] < p[j]; }
func (p IntArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i]; }

// Sort is a convenience method.
func (p IntArray) Sort()       { Sort(p); }

// FloatArray attaches the methods of SortInterface to []float, sorting in increasing order.
type FloatArray  []float

func (p FloatArray) Len() int            { return len(p); }
func (p FloatArray) Less(i, j int) bool  { return p[i] < p[j]; }
func (p FloatArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i]; }

// Sort is a convenience method.
ffunc (p FloatArray) Sort()       { Sort(p); }

// StringArray attaches the methods of SortInterface to []string, sorting in increasing order.
type StringArray []string

func (p StringArray) Len() int            { return len(p); }
func (p StringArray) Less(i, j int) bool  { return p[i] < p[j]; }
func (p StringArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i]; }

// Sort is a convenience method.
ffunc (p StringArray) Sort()       { Sort(p); }

// Convenience wrappers for common cases

// SortInts sorts an array of ints in increasing order.
func SortInts(a []int)        { Sort(IntArray(a)); }
// SortFloats sorts an array of floats in increasing order.
func SortFloats(a []float)    { Sort(FloatArray(a)); }
// SortStrings sorts an array of strings in increasing order.
func SortStrings(a []string)  { Sort(StringArray(a)); }

// IntsAreSorted tests whether an array of ints is sorted in increasing order.
func IntsAreSorted(a []int) bool       { return IsSorted(IntArray(a)); }
// FloatsAreSorted tests whether an array of floats is sorted in increasing order.
func FloatsAreSorted(a []float) bool   { return IsSorted(FloatArray(a)); }
// StringsAreSorted tests whether an array of strings is sorted in increasing order.
func StringsAreSorted(a []string) bool { return IsSorted(StringArray(a)); }
<commit_msg>Build fix: fix typo in sort pkg.<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// The sort package provides primitives for sorting arrays
// and user-defined collections.
package sort

// SortInterface is the interface that a type, typically a collection,
// must implement for its contents to be sorted in increasing order.
// Its methods require that the elements of the collection be enumerated
// by an integer index.
type SortInterface interface {
	// Len is the number of elements in the collection.
	Len() int;
	// Less returns whether the element with index i is should sort
	// before the element with index j.
	// TODO(r): should this method be renamed Before?
	Less(i, j int) bool;
	// Swap swaps the elements with indexes i and j.
	Swap(i, j int);
}

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

// Insertion sort
func insertionSort(data SortInterface, a, b int) {
	for i := a+1; i < b; i++ {
		for j := i; j > a && data.Less(j, j-1); j-- {
			data.Swap(j, j-1);
		}
	}
}

// Quicksort, following Bentley and McIlroy,
// ``Engineering a Sort Function,'' SP&E November 1993.

// Move the median of the three values data[a], data[b], data[c] into data[a].
func medianOfThree(data SortInterface, a, b, c int) {
	m0 := b;
	m1 := a;
	m2 := c;
	// bubble sort on 3 elements
	if data.Less(m1, m0) { data.Swap(m1, m0); }
	if data.Less(m2, m1) { data.Swap(m2, m1); }
	if data.Less(m1, m0) { data.Swap(m1, m0); }
	// now data[m0] <= data[m1] <= data[m2]
}

func swapRange(data SortInterface, a, b, n int) {
	for i := 0; i < n; i++ {
		data.Swap(a+i, b+i);
	}
}

func doPivot(data SortInterface, lo, hi int) (midlo, midhi int) {
	m := (lo+hi)/2;
	if hi - lo > 40 {
		// Tukey's ``Ninther,'' median of three medians of three.
		s := (hi - lo) / 8;
		medianOfThree(data, lo, lo+s, lo+2*s);
		medianOfThree(data, m, m-s, m+s);
		medianOfThree(data, hi-1, hi-1-s, hi-1-2*s);
	}
	medianOfThree(data, lo, m, hi-1);

	// Invariants are:
	//	data[lo] = pivot (set up by ChoosePivot)
	//	data[lo <= i < a] = pivot
	//	data[a <= i < b] < pivot
	//	data[b <= i < c] is unexamined
	//	data[c <= i < d] > pivot
	//	data[d <= i < hi] = pivot
	//
	// Once b meets c, can swap the "= pivot" sections
	// into the middle of the array.
	pivot := lo;
	a, b, c, d := lo+1, lo+1, hi, hi;
	for b < c {
		if data.Less(b, pivot) {	// data[b] < pivot
			b++;
			continue;
		}
		if !data.Less(pivot, b) {	// data[b] = pivot
			data.Swap(a, b);
			a++;
			b++;
			continue;
		}
		if data.Less(pivot, c-1) {	// data[c-1] > pivot
			c--;
			continue;
		}
		if !data.Less(c-1, pivot) {	// data[c-1] = pivot
			data.Swap(c-1, d-1);
			c--;
			d--;
			continue;
		}
		// data[b] > pivot; data[c-1] < pivot
		data.Swap(b, c-1);
		b++;
		c--;
	}

	n := min(b-a, a-lo);
	swapRange(data, lo, b-n, n);

	n = min(hi-d, d-c);
	swapRange(data, c, hi-n, n);

	return lo+b-a, hi-(d-c);
}

func quickSort(data SortInterface, a, b int) {
	if b - a > 7 {
		mlo, mhi := doPivot(data, a, b);
		quickSort(data, a, mlo);
		quickSort(data, mhi, b);
	} else if b - a > 1 {
		insertionSort(data, a, b);
	}
}

func Sort(data SortInterface) {
	quickSort(data, 0, data.Len());
}

func IsSorted(data SortInterface) bool {
	n := data.Len();
	for i := n - 1; i > 0; i-- {
		if data.Less(i, i - 1) {
			return false;
		}
	}
	return true;
}

// Convenience types for common cases

// IntArray attaches the methods of SortInterface to []int, sorting in increasing order.
type IntArray []int

func (p IntArray) Len() int            { return len(p); }
func (p IntArray) Less(i, j int) bool  { return p[i] < p[j]; }
func (p IntArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i]; }

// Sort is a convenience method.
func (p IntArray) Sort()       { Sort(p); }

// FloatArray attaches the methods of SortInterface to []float, sorting in increasing order.
type FloatArray  []float

func (p FloatArray) Len() int            { return len(p); }
func (p FloatArray) Less(i, j int) bool  { return p[i] < p[j]; }
func (p FloatArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i]; }

// Sort is a convenience method.
func (p FloatArray) Sort()       { Sort(p); }

// StringArray attaches the methods of SortInterface to []string, sorting in increasing order.
type StringArray []string

func (p StringArray) Len() int            { return len(p); }
func (p StringArray) Less(i, j int) bool  { return p[i] < p[j]; }
func (p StringArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i]; }

// Sort is a convenience method.
func (p StringArray) Sort()       { Sort(p); }

// Convenience wrappers for common cases

// SortInts sorts an array of ints in increasing order.
func SortInts(a []int)        { Sort(IntArray(a)); }
// SortFloats sorts an array of floats in increasing order.
func SortFloats(a []float)    { Sort(FloatArray(a)); }
// SortStrings sorts an array of strings in increasing order.
func SortStrings(a []string)  { Sort(StringArray(a)); }

// IntsAreSorted tests whether an array of ints is sorted in increasing order.
func IntsAreSorted(a []int) bool       { return IsSorted(IntArray(a)); }
// FloatsAreSorted tests whether an array of floats is sorted in increasing order.
func FloatsAreSorted(a []float) bool   { return IsSorted(FloatArray(a)); }
// StringsAreSorted tests whether an array of strings is sorted in increasing order.
func StringsAreSorted(a []string) bool { return IsSorted(StringArray(a)); }
<|endoftext|>


<commit_before>package main

import (
	"eaciit/gdrj/model"
	"eaciit/gdrj/modules"
	"os"

	"strings"
	"time"

	"github.com/eaciit/dbox"
	"github.com/eaciit/orm/v1"
	"github.com/eaciit/toolkit"
)

var conn dbox.IConnection
var count int
var ratioTableName string

var (
	yearttxt                    = "2016"
	sourcetablename             = "salespls-summary-" + yearttxt + "-vdistrd"
	calctablename               = "salespls-summary"
	desttablename               = "salespls-summary"
	t0                          time.Time
	fiscalyear, iscount, scount int
	data                        map[string]float64
	masters                     = toolkit.M{}
)

type plalloc struct {
	Key      string
	Ref1     float64
	Current  float64
	Expect   float64
	Absorbed float64
}

type allocmap map[string]*plalloc

var plallocs = allocmap{}
var totals = allocmap{}
var ples = allocmap{}
var f = dbox.Eq("key.trxsrc", "RECLASSPROMOSPGRDMT")
var fsalesrd = dbox.Eq("key.customer_reportchannel", "RD")

func adjustAllocs(allocsmap *allocmap, key string, current, expect, absorbed, ref1 float64) {
	allocs := *allocsmap
	alloc := allocs[key]
	if alloc == nil {
		alloc = new(plalloc)
		alloc.Key = key
	}
	alloc.Current += current
	alloc.Expect += expect
	alloc.Ref1 += ref1
	alloc.Absorbed += absorbed
	allocs[key] = alloc
	*allocsmap = allocs
}

func main() {
	t0 = time.Now()

	setinitialconnection()
	defer gdrj.CloseDb()
	prepmastercalc()

	toolkit.Println("Start data query...")
	tablenames := []string{
		"salespls-summary"}

	for _, tn := range tablenames {
		e := buildRatio(tn)
		if e != nil {
			toolkit.Printfn("Build ratio error: %s - %s", tn, e.Error())
			return
		}

		e = processTable(tn)
		if e != nil {
			toolkit.Printfn("Process table error: %s - %s", tn, e.Error())
			return
		}
	}
}

func buildRatio(tn string) error {
	fiscal1 := toolkit.ToInt(yearttxt, toolkit.RoundingAuto)
	fiscal0 := fiscal1 - 1
	fiscaltxt := toolkit.Sprintf("%d-%d", fiscal0, fiscal1)
	cursor, _ := conn.NewQuery().From(calctablename).
		Where(dbox.Eq("key.date_fiscal", fiscaltxt)).
		//Group("key.customer_reportchannel").
		//Aggr(dbox.AggrSum, "PL8A", "PL8A").
		//Select().
		Cursor(nil)
	defer cursor.Close()

	i := 0
	count := cursor.Count()
	t0 := time.Now()
	mstone := 0
	total := float64(0)
	for {
		mtgtratio := toolkit.M{}
		efetch := cursor.Fetch(&mtgtratio, 1, false)
		if efetch != nil {
			break
		}
		i++
		makeProgressLog("MT/GT Ratio", i, count, 5, &mstone, t0)
		key := mtgtratio.Get("key", toolkit.M{}).(toolkit.M)
		reportchannel := key.GetString("customer_reportchannel")
		if reportchannel == "MT" || reportchannel == "GT" {
			sales := mtgtratio.GetFloat64("PL8A")
			total += sales
			adjustAllocs(&totals, reportchannel, sales, 0, 0, 0)
		}
	}
	for _, alloc := range totals {
		alloc.Expect = alloc.Current / total
		alloc.Ref1 = total
	}
	toolkit.Printfn("MT/GT Ratio: %s", toolkit.JsonString(totals))

	return nil
}

func makeProgressLog(reference string, i, count, step int, current *int, tstart time.Time) int {
	perstep := count * step / 100
	icurrent := *current
	if icurrent == 0 {
		icurrent = perstep
	}
	pct := i * 100 / count
	if i >= icurrent {
		toolkit.Printfn("Processing %s, %d of %d [%d pct] in %s",
			reference, i, count, pct, time.Since(tstart).String())
		icurrent += perstep
	}
	*current = icurrent
	return icurrent
}

func processTable(tn string) error {
	toolkit.Printfn("Start processing allocation")
	cursor, _ := conn.NewQuery().From(sourcetablename).
		Select().Cursor(nil)
	defer cursor.Close()

	//plmodels := masters["plmodel"].(map[string]*gdrj.PLModel)
	qsave := conn.NewQuery().SetConfig("multiexec", true).From(desttablename).Save()

	count := cursor.Count()
	i := 0
	step := count / 20
	mstone := step
	t0 = time.Now()
	for {
		mr := toolkit.M{}
		ef := cursor.Fetch(&mr, 1, false)
		if ef != nil {
			break
		}

		i++
		makeProgressLog("Processing", i, count, 5, &mstone, t0)
		//key := mr.Get("key", toolkit.M{}).(toolkit.M)
		//fiscal := key.GetString("date_fiscal")

		mrid := mr.GetString("_id")
		key := mr.Get("key", toolkit.M{}).(toolkit.M)
		salesvalue := mr.GetFloat64("PL8A")
		grossvalue := mr.GetFloat64("PL2")

		for channel, total := range totals {
			mrk := toolkit.M{}
			mrkkey := toolkit.M{}
			for k, v := range key {
				mrkkey.Set(k, v)
			}
			mrkkey.Set("trxsrc", "pushrdreversesbymks")
			mrkkey.Set("customer_reportchannel", channel)
			mrkkey.Set("customer_channelname", channel)
			if channel == "MT" {
				mrkkey.Set("customer_channelid", "I3")
			} else if channel == "GT" {
				mrkkey.Set("customer_channelid", "I2")
			}

			mrsales := -salesvalue * total.Expect
			mrgross := -grossvalue * total.Expect
			mrdiscount := mrsales - mrgross
			mrk.Set("key", mrkkey)
			mrk.Set("PL1", mrgross)
			mrk.Set("PL7", mrdiscount)
			mrk.Set("PL8A", mrsales)

			mrk.Set("_id", toolkit.Sprintf("%s|pushrdreverse|%s", mrid, channel))
			gdrj.CalcSum(mrk, masters)
			esavereverse := qsave.Exec(toolkit.M{}.Set("data", mrk))
			if esavereverse != nil {
				return esavereverse
			}
		}

		for k, v := range mr {
			if strings.HasPrefix(k, "PL") {
				if k == "PL8" || k == "PL2" {
					mr.Set(k, v)
				} else {
					mr.Set(k, float64(0))
				}
			}
		}

		key.Set("trxsrc", "rdsbymks")
		mr.Set("key", key)
		gdrj.CalcSum(mr, masters)
		esave := qsave.Exec(toolkit.M{}.Set("data", mr))
		if esave != nil {
			return esave
		}
	}
	return nil
}

func buildmap(holder interface{},
	fnModel func() orm.IModel,
	filter *dbox.Filter,
	fnIter func(holder interface{}, obj interface{})) interface{} {
	crx, ecrx := gdrj.Find(fnModel(), filter, nil)
	if ecrx != nil {
		toolkit.Printfn("Cursor Error: %s", ecrx.Error())
		os.Exit(100)
	}
	defer crx.Close()
	for {
		s := fnModel()
		e := crx.Fetch(s, 1, false)
		if e != nil {
			break
		}
		fnIter(holder, s)
	}
	return holder
}

func prepmastercalc() {
	toolkit.Println("--> PL MODEL")
	masters.Set("plmodel", buildmap(map[string]*gdrj.PLModel{},
		func() orm.IModel {
			return new(gdrj.PLModel)
		},
		nil,
		func(holder, obj interface{}) {
			h := holder.(map[string]*gdrj.PLModel)
			o := obj.(*gdrj.PLModel)
			h[o.ID] = o
		}).(map[string]*gdrj.PLModel))
}

func setinitialconnection() {
	var err error
	conn, err = modules.GetDboxIConnection("db_godrej")

	if err != nil {
		toolkit.Println("Initial connection found : ", err)
		os.Exit(1)
	}

	err = gdrj.SetDb(conn)
	if err != nil {
		toolkit.Println("Initial connection found : ", err)
		os.Exit(1)
	}
}
<commit_msg>fixkey<commit_after>package main

import (
	"eaciit/gdrj/model"
	"eaciit/gdrj/modules"
	"os"

	"strings"
	"time"

	"github.com/eaciit/dbox"
	"github.com/eaciit/orm/v1"
	"github.com/eaciit/toolkit"
)

var conn dbox.IConnection
var count int
var ratioTableName string

var (
	yearttxt                    = "2016"
	sourcetablename             = "salespls-summary-" + yearttxt + "-vdistrd"
	calctablename               = "salespls-summary"
	desttablename               = "salespls-summary"
	t0                          time.Time
	fiscalyear, iscount, scount int
	data                        map[string]float64
	masters                     = toolkit.M{}
)

type plalloc struct {
	Key      string
	Ref1     float64
	Current  float64
	Expect   float64
	Absorbed float64
}

type allocmap map[string]*plalloc

var plallocs = allocmap{}
var totals = allocmap{}
var ples = allocmap{}
var f = dbox.Eq("key.trxsrc", "RECLASSPROMOSPGRDMT")
var fsalesrd = dbox.Eq("key.customer_reportchannel", "RD")

func adjustAllocs(allocsmap *allocmap, key string, current, expect, absorbed, ref1 float64) {
	allocs := *allocsmap
	alloc := allocs[key]
	if alloc == nil {
		alloc = new(plalloc)
		alloc.Key = key
	}
	alloc.Current += current
	alloc.Expect += expect
	alloc.Ref1 += ref1
	alloc.Absorbed += absorbed
	allocs[key] = alloc
	*allocsmap = allocs
}

func main() {
	t0 = time.Now()

	setinitialconnection()
	defer gdrj.CloseDb()
	prepmastercalc()

	toolkit.Println("Start data query...")
	tablenames := []string{
		"salespls-summary"}

	for _, tn := range tablenames {
		e := buildRatio(tn)
		if e != nil {
			toolkit.Printfn("Build ratio error: %s - %s", tn, e.Error())
			return
		}

		e = processTable(tn)
		if e != nil {
			toolkit.Printfn("Process table error: %s - %s", tn, e.Error())
			return
		}
	}
}

func buildRatio(tn string) error {
	fiscal1 := toolkit.ToInt(yearttxt, toolkit.RoundingAuto)
	fiscal0 := fiscal1 - 1
	fiscaltxt := toolkit.Sprintf("%d-%d", fiscal0, fiscal1)
	cursor, _ := conn.NewQuery().From(calctablename).
		Where(dbox.Eq("key.date_fiscal", fiscaltxt)).
		//Group("key.customer_reportchannel").
		//Aggr(dbox.AggrSum, "PL8A", "PL8A").
		//Select().
		Cursor(nil)
	defer cursor.Close()

	i := 0
	count := cursor.Count()
	t0 := time.Now()
	mstone := 0
	total := float64(0)
	for {
		mtgtratio := toolkit.M{}
		efetch := cursor.Fetch(&mtgtratio, 1, false)
		if efetch != nil {
			break
		}
		i++
		makeProgressLog("MT/GT Ratio", i, count, 5, &mstone, t0)
		key := mtgtratio.Get("key", toolkit.M{}).(toolkit.M)
		reportchannel := key.GetString("customer_reportchannel")
		if reportchannel == "MT" || reportchannel == "GT" {
			sales := mtgtratio.GetFloat64("PL8A")
			total += sales
			adjustAllocs(&totals, reportchannel, sales, 0, 0, 0)
		}
	}
	for _, alloc := range totals {
		alloc.Expect = alloc.Current / total
		alloc.Ref1 = total
	}
	toolkit.Printfn("MT/GT Ratio: %s", toolkit.JsonString(totals))

	return nil
}

func makeProgressLog(reference string, i, count, step int, current *int, tstart time.Time) int {
	perstep := count * step / 100
	icurrent := *current
	if icurrent == 0 {
		icurrent = perstep
	}
	pct := i * 100 / count
	if i >= icurrent {
		toolkit.Printfn("Processing %s, %d of %d [%d pct] in %s",
			reference, i, count, pct, time.Since(tstart).String())
		icurrent += perstep
	}
	*current = icurrent
	return icurrent
}

func processTable(tn string) error {
	toolkit.Printfn("Start processing allocation")
	cursor, _ := conn.NewQuery().From(sourcetablename).
		Select().Cursor(nil)
	defer cursor.Close()

	//plmodels := masters["plmodel"].(map[string]*gdrj.PLModel)
	qsave := conn.NewQuery().SetConfig("multiexec", true).From(desttablename).Save()

	count := cursor.Count()
	i := 0
	step := count / 20
	mstone := step
	t0 = time.Now()
	for {
		mr := toolkit.M{}
		ef := cursor.Fetch(&mr, 1, false)
		if ef != nil {
			break
		}

		i++
		makeProgressLog("Processing", i, count, 5, &mstone, t0)
		//key := mr.Get("key", toolkit.M{}).(toolkit.M)
		//fiscal := key.GetString("date_fiscal")

		mrid := mr.GetString("_id")
		key := mr.Get("key", toolkit.M{}).(toolkit.M)
		salesvalue := mr.GetFloat64("PL8A")
		grossvalue := mr.GetFloat64("PL2")

		for channel, total := range totals {
			mrk := toolkit.M{}
			mrkkey := toolkit.M{}
			for k, v := range key {
				mrkkey.Set(k, v)
			}
			mrkkey.Set("trxsrc", "pushrdreversesbymks")
			mrkkey.Set("customer_reportchannel", channel)
			mrkkey.Set("customer_channelname", channel)
			if channel == "MT" {
				mrkkey.Set("customer_channelid", "I3")
			} else if channel == "GT" {
				mrkkey.Set("customer_channelid", "I2")
			}

			mrsales := -salesvalue * total.Expect
			mrgross := -grossvalue * total.Expect
			mrdiscount := mrsales - mrgross
			mrk.Set("key", mrkkey)
			mrk.Set("PL1", mrgross)
			mrk.Set("PL7", mrdiscount)
			mrk.Set("PL8A", mrsales)

			mrk.Set("_id", toolkit.Sprintf("%s|pushrdreverse|%s", mrid, channel))
			gdrj.CalcSum(mrk, masters)
			esavereverse := qsave.Exec(toolkit.M{}.Set("data", mrk))
			if esavereverse != nil {
				return esavereverse
			}
		}

		for k, v := range mr {
			if strings.HasPrefix(k, "PL") {
				if k == "PL8" || k == "PL2" {
					mr.Set(k, v)
				} else {
					mr.Set(k, float64(0))
				}
			}
		}

		key.Set("trxsrc", "rdsbymks")
		mr.Set("key", key)
		mr.Set("_id", mrid+"|rdsbymks")
		gdrj.CalcSum(mr, masters)
		esave := qsave.Exec(toolkit.M{}.Set("data", mr))
		if esave != nil {
			return esave
		}
	}
	return nil
}

func buildmap(holder interface{},
	fnModel func() orm.IModel,
	filter *dbox.Filter,
	fnIter func(holder interface{}, obj interface{})) interface{} {
	crx, ecrx := gdrj.Find(fnModel(), filter, nil)
	if ecrx != nil {
		toolkit.Printfn("Cursor Error: %s", ecrx.Error())
		os.Exit(100)
	}
	defer crx.Close()
	for {
		s := fnModel()
		e := crx.Fetch(s, 1, false)
		if e != nil {
			break
		}
		fnIter(holder, s)
	}
	return holder
}

func prepmastercalc() {
	toolkit.Println("--> PL MODEL")
	masters.Set("plmodel", buildmap(map[string]*gdrj.PLModel{},
		func() orm.IModel {
			return new(gdrj.PLModel)
		},
		nil,
		func(holder, obj interface{}) {
			h := holder.(map[string]*gdrj.PLModel)
			o := obj.(*gdrj.PLModel)
			h[o.ID] = o
		}).(map[string]*gdrj.PLModel))
}

func setinitialconnection() {
	var err error
	conn, err = modules.GetDboxIConnection("db_godrej")

	if err != nil {
		toolkit.Println("Initial connection found : ", err)
		os.Exit(1)
	}

	err = gdrj.SetDb(conn)
	if err != nil {
		toolkit.Println("Initial connection found : ", err)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package arduino

import (
	"github.com/distributed/sers"
	"log"
)

func SetColor(color string) (err error) {
	s, err := sers.Open("COM6")
	if err != nil {
		log.Printf("Error connecting to Arduino: %v", err)
		return
	}
	_, err := s.Write([]byte(color))
	if err != nil {
		log.Printf("Error setting LED to green: %v", err)
	}
	s.Close()
	return
}
<commit_msg>fixed variable declaration<commit_after>package arduino

import (
	"github.com/distributed/sers"
	"log"
)

func SetColor(color string) (err error) {
	s, err := sers.Open("COM6")
	if err != nil {
		log.Printf("Error connecting to Arduino: %v", err)
		return
	}
	_, err = s.Write([]byte(color))
	if err != nil {
		log.Printf("Error setting LED to green: %v", err)
	}
	s.Close()
	return
}
<|endoftext|>


<commit_before>// Code generated by counterfeiter. DO NOT EDIT.
package providerfakes

import (
	"net/http"
	"sync"

	"code.cloudfoundry.org/lager"
	"github.com/concourse/atc/auth/provider"
	"golang.org/x/net/context"
	"golang.org/x/oauth2"
)

type FakeProvider struct {
	PreTokenClientStub        func() (*http.Client, error)
	preTokenClientMutex       sync.RWMutex
	preTokenClientArgsForCall []struct{}
	preTokenClientReturns     struct {
		result1 *http.Client
		result2 error
	}
	preTokenClientReturnsOnCall map[int]struct {
		result1 *http.Client
		result2 error
	}
	AuthCodeURLStub        func(string, ...oauth2.AuthCodeOption) string
	authCodeURLMutex       sync.RWMutex
	authCodeURLArgsForCall []struct {
		arg1 string
		arg2 []oauth2.AuthCodeOption
	}
	authCodeURLReturns struct {
		result1 string
	}
	authCodeURLReturnsOnCall map[int]struct {
		result1 string
	}
	ExchangeStub        func(context.Context, string) (*oauth2.Token, error)
	exchangeMutex       sync.RWMutex
	exchangeArgsForCall []struct {
		arg1 context.Context
		arg2 string
	}
	exchangeReturns struct {
		result1 *oauth2.Token
		result2 error
	}
	exchangeReturnsOnCall map[int]struct {
		result1 *oauth2.Token
		result2 error
	}
	ClientStub        func(context.Context, *oauth2.Token) *http.Client
	clientMutex       sync.RWMutex
	clientArgsForCall []struct {
		arg1 context.Context
		arg2 *oauth2.Token
	}
	clientReturns struct {
		result1 *http.Client
	}
	clientReturnsOnCall map[int]struct {
		result1 *http.Client
	}
	VerifyStub        func(lager.Logger, *http.Client) (bool, error)
	verifyMutex       sync.RWMutex
	verifyArgsForCall []struct {
		arg1 lager.Logger
		arg2 *http.Client
	}
	verifyReturns struct {
		result1 bool
		result2 error
	}
	verifyReturnsOnCall map[int]struct {
		result1 bool
		result2 error
	}
	invocations      map[string][][]interface{}
	invocationsMutex sync.RWMutex
}

func (fake *FakeProvider) PreTokenClient() (*http.Client, error) {
	fake.preTokenClientMutex.Lock()
	ret, specificReturn := fake.preTokenClientReturnsOnCall[len(fake.preTokenClientArgsForCall)]
	fake.preTokenClientArgsForCall = append(fake.preTokenClientArgsForCall, struct{}{})
	fake.recordInvocation("PreTokenClient", []interface{}{})
	fake.preTokenClientMutex.Unlock()
	if fake.PreTokenClientStub != nil {
		return fake.PreTokenClientStub()
	}
	if specificReturn {
		return ret.result1, ret.result2
	}
	return fake.preTokenClientReturns.result1, fake.preTokenClientReturns.result2
}

func (fake *FakeProvider) PreTokenClientCallCount() int {
	fake.preTokenClientMutex.RLock()
	defer fake.preTokenClientMutex.RUnlock()
	return len(fake.preTokenClientArgsForCall)
}

func (fake *FakeProvider) PreTokenClientReturns(result1 *http.Client, result2 error) {
	fake.PreTokenClientStub = nil
	fake.preTokenClientReturns = struct {
		result1 *http.Client
		result2 error
	}{result1, result2}
}

func (fake *FakeProvider) PreTokenClientReturnsOnCall(i int, result1 *http.Client, result2 error) {
	fake.PreTokenClientStub = nil
	if fake.preTokenClientReturnsOnCall == nil {
		fake.preTokenClientReturnsOnCall = make(map[int]struct {
			result1 *http.Client
			result2 error
		})
	}
	fake.preTokenClientReturnsOnCall[i] = struct {
		result1 *http.Client
		result2 error
	}{result1, result2}
}

func (fake *FakeProvider) AuthCodeURL(arg1 string, arg2 ...oauth2.AuthCodeOption) string {
	fake.authCodeURLMutex.Lock()
	ret, specificReturn := fake.authCodeURLReturnsOnCall[len(fake.authCodeURLArgsForCall)]
	fake.authCodeURLArgsForCall = append(fake.authCodeURLArgsForCall, struct {
		arg1 string
		arg2 []oauth2.AuthCodeOption
	}{arg1, arg2})
	fake.recordInvocation("AuthCodeURL", []interface{}{arg1, arg2})
	fake.authCodeURLMutex.Unlock()
	if fake.AuthCodeURLStub != nil {
		return fake.AuthCodeURLStub(arg1, arg2...)
	}
	if specificReturn {
		return ret.result1
	}
	return fake.authCodeURLReturns.result1
}

func (fake *FakeProvider) AuthCodeURLCallCount() int {
	fake.authCodeURLMutex.RLock()
	defer fake.authCodeURLMutex.RUnlock()
	return len(fake.authCodeURLArgsForCall)
}

func (fake *FakeProvider) AuthCodeURLArgsForCall(i int) (string, []oauth2.AuthCodeOption) {
	fake.authCodeURLMutex.RLock()
	defer fake.authCodeURLMutex.RUnlock()
	return fake.authCodeURLArgsForCall[i].arg1, fake.authCodeURLArgsForCall[i].arg2
}

func (fake *FakeProvider) AuthCodeURLReturns(result1 string) {
	fake.AuthCodeURLStub = nil
	fake.authCodeURLReturns = struct {
		result1 string
	}{result1}
}

func (fake *FakeProvider) AuthCodeURLReturnsOnCall(i int, result1 string) {
	fake.AuthCodeURLStub = nil
	if fake.authCodeURLReturnsOnCall == nil {
		fake.authCodeURLReturnsOnCall = make(map[int]struct {
			result1 string
		})
	}
	fake.authCodeURLReturnsOnCall[i] = struct {
		result1 string
	}{result1}
}

func (fake *FakeProvider) Exchange(arg1 context.Context, arg2 string) (*oauth2.Token, error) {
	fake.exchangeMutex.Lock()
	ret, specificReturn := fake.exchangeReturnsOnCall[len(fake.exchangeArgsForCall)]
	fake.exchangeArgsForCall = append(fake.exchangeArgsForCall, struct {
		arg1 context.Context
		arg2 string
	}{arg1, arg2})
	fake.recordInvocation("Exchange", []interface{}{arg1, arg2})
	fake.exchangeMutex.Unlock()
	if fake.ExchangeStub != nil {
		return fake.ExchangeStub(arg1, arg2)
	}
	if specificReturn {
		return ret.result1, ret.result2
	}
	return fake.exchangeReturns.result1, fake.exchangeReturns.result2
}

func (fake *FakeProvider) ExchangeCallCount() int {
	fake.exchangeMutex.RLock()
	defer fake.exchangeMutex.RUnlock()
	return len(fake.exchangeArgsForCall)
}

func (fake *FakeProvider) ExchangeArgsForCall(i int) (context.Context, string) {
	fake.exchangeMutex.RLock()
	defer fake.exchangeMutex.RUnlock()
	return fake.exchangeArgsForCall[i].arg1, fake.exchangeArgsForCall[i].arg2
}

func (fake *FakeProvider) ExchangeReturns(result1 *oauth2.Token, result2 error) {
	fake.ExchangeStub = nil
	fake.exchangeReturns = struct {
		result1 *oauth2.Token
		result2 error
	}{result1, result2}
}

func (fake *FakeProvider) ExchangeReturnsOnCall(i int, result1 *oauth2.Token, result2 error) {
	fake.ExchangeStub = nil
	if fake.exchangeReturnsOnCall == nil {
		fake.exchangeReturnsOnCall = make(map[int]struct {
			result1 *oauth2.Token
			result2 error
		})
	}
	fake.exchangeReturnsOnCall[i] = struct {
		result1 *oauth2.Token
		result2 error
	}{result1, result2}
}

func (fake *FakeProvider) Client(arg1 context.Context, arg2 *oauth2.Token) *http.Client {
	fake.clientMutex.Lock()
	ret, specificReturn := fake.clientReturnsOnCall[len(fake.clientArgsForCall)]
	fake.clientArgsForCall = append(fake.clientArgsForCall, struct {
		arg1 context.Context
		arg2 *oauth2.Token
	}{arg1, arg2})
	fake.recordInvocation("Client", []interface{}{arg1, arg2})
	fake.clientMutex.Unlock()
	if fake.ClientStub != nil {
		return fake.ClientStub(arg1, arg2)
	}
	if specificReturn {
		return ret.result1
	}
	return fake.clientReturns.result1
}

func (fake *FakeProvider) ClientCallCount() int {
	fake.clientMutex.RLock()
	defer fake.clientMutex.RUnlock()
	return len(fake.clientArgsForCall)
}

func (fake *FakeProvider) ClientArgsForCall(i int) (context.Context, *oauth2.Token) {
	fake.clientMutex.RLock()
	defer fake.clientMutex.RUnlock()
	return fake.clientArgsForCall[i].arg1, fake.clientArgsForCall[i].arg2
}

func (fake *FakeProvider) ClientReturns(result1 *http.Client) {
	fake.ClientStub = nil
	fake.clientReturns = struct {
		result1 *http.Client
	}{result1}
}

func (fake *FakeProvider) ClientReturnsOnCall(i int, result1 *http.Client) {
	fake.ClientStub = nil
	if fake.clientReturnsOnCall == nil {
		fake.clientReturnsOnCall = make(map[int]struct {
			result1 *http.Client
		})
	}
	fake.clientReturnsOnCall[i] = struct {
		result1 *http.Client
	}{result1}
}

func (fake *FakeProvider) Verify(arg1 lager.Logger, arg2 *http.Client) (bool, error) {
	fake.verifyMutex.Lock()
	ret, specificReturn := fake.verifyReturnsOnCall[len(fake.verifyArgsForCall)]
	fake.verifyArgsForCall = append(fake.verifyArgsForCall, struct {
		arg1 lager.Logger
		arg2 *http.Client
	}{arg1, arg2})
	fake.recordInvocation("Verify", []interface{}{arg1, arg2})
	fake.verifyMutex.Unlock()
	if fake.VerifyStub != nil {
		return fake.VerifyStub(arg1, arg2)
	}
	if specificReturn {
		return ret.result1, ret.result2
	}
	return fake.verifyReturns.result1, fake.verifyReturns.result2
}

func (fake *FakeProvider) VerifyCallCount() int {
	fake.verifyMutex.RLock()
	defer fake.verifyMutex.RUnlock()
	return len(fake.verifyArgsForCall)
}

func (fake *FakeProvider) VerifyArgsForCall(i int) (lager.Logger, *http.Client) {
	fake.verifyMutex.RLock()
	defer fake.verifyMutex.RUnlock()
	return fake.verifyArgsForCall[i].arg1, fake.verifyArgsForCall[i].arg2
}

func (fake *FakeProvider) VerifyReturns(result1 bool, result2 error) {
	fake.VerifyStub = nil
	fake.verifyReturns = struct {
		result1 bool
		result2 error
	}{result1, result2}
}

func (fake *FakeProvider) VerifyReturnsOnCall(i int, result1 bool, result2 error) {
	fake.VerifyStub = nil
	if fake.verifyReturnsOnCall == nil {
		fake.verifyReturnsOnCall = make(map[int]struct {
			result1 bool
			result2 error
		})
	}
	fake.verifyReturnsOnCall[i] = struct {
		result1 bool
		result2 error
	}{result1, result2}
}

func (fake *FakeProvider) Invocations() map[string][][]interface{} {
	fake.invocationsMutex.RLock()
	defer fake.invocationsMutex.RUnlock()
	fake.preTokenClientMutex.RLock()
	defer fake.preTokenClientMutex.RUnlock()
	fake.authCodeURLMutex.RLock()
	defer fake.authCodeURLMutex.RUnlock()
	fake.exchangeMutex.RLock()
	defer fake.exchangeMutex.RUnlock()
	fake.clientMutex.RLock()
	defer fake.clientMutex.RUnlock()
	fake.verifyMutex.RLock()
	defer fake.verifyMutex.RUnlock()
	copiedInvocations := map[string][][]interface{}{}
	for key, value := range fake.invocations {
		copiedInvocations[key] = value
	}
	return copiedInvocations
}

func (fake *FakeProvider) recordInvocation(key string, args []interface{}) {
	fake.invocationsMutex.Lock()
	defer fake.invocationsMutex.Unlock()
	if fake.invocations == nil {
		fake.invocations = map[string][][]interface{}{}
	}
	if fake.invocations[key] == nil {
		fake.invocations[key] = [][]interface{}{}
	}
	fake.invocations[key] = append(fake.invocations[key], args)
}

var _ provider.Provider = new(FakeProvider)
<commit_msg>Update Provider fake<commit_after>// Code generated by counterfeiter. DO NOT EDIT.
package providerfakes

import (
	"net/http"
	"sync"

	"code.cloudfoundry.org/lager"
	"github.com/concourse/atc/auth/provider"
	"golang.org/x/net/context"
	"golang.org/x/oauth2"
)

type FakeProvider struct {
	PreTokenClientStub        func() (*http.Client, error)
	preTokenClientMutex       sync.RWMutex
	preTokenClientArgsForCall []struct{}
	preTokenClientReturns     struct {
		result1 *http.Client
		result2 error
	}
	preTokenClientReturnsOnCall map[int]struct {
		result1 *http.Client
		result2 error
	}
	AuthCodeURLStub        func(string, ...oauth2.AuthCodeOption) string
	authCodeURLMutex       sync.RWMutex
	authCodeURLArgsForCall []struct {
		arg1 string
		arg2 []oauth2.AuthCodeOption
	}
	authCodeURLReturns struct {
		result1 string
	}
	authCodeURLReturnsOnCall map[int]struct {
		result1 string
	}
	ExchangeStub        func(context.Context, *http.Request) (*oauth2.Token, error)
	exchangeMutex       sync.RWMutex
	exchangeArgsForCall []struct {
		arg1 context.Context
		arg2 *http.Request
	}
	exchangeReturns struct {
		result1 *oauth2.Token
		result2 error
	}
	exchangeReturnsOnCall map[int]struct {
		result1 *oauth2.Token
		result2 error
	}
	ClientStub        func(context.Context, *oauth2.Token) *http.Client
	clientMutex       sync.RWMutex
	clientArgsForCall []struct {
		arg1 context.Context
		arg2 *oauth2.Token
	}
	clientReturns struct {
		result1 *http.Client
	}
	clientReturnsOnCall map[int]struct {
		result1 *http.Client
	}
	VerifyStub        func(lager.Logger, *http.Client) (bool, error)
	verifyMutex       sync.RWMutex
	verifyArgsForCall []struct {
		arg1 lager.Logger
		arg2 *http.Client
	}
	verifyReturns struct {
		result1 bool
		result2 error
	}
	verifyReturnsOnCall map[int]struct {
		result1 bool
		result2 error
	}
	invocations      map[string][][]interface{}
	invocationsMutex sync.RWMutex
}

func (fake *FakeProvider) PreTokenClient() (*http.Client, error) {
	fake.preTokenClientMutex.Lock()
	ret, specificReturn := fake.preTokenClientReturnsOnCall[len(fake.preTokenClientArgsForCall)]
	fake.preTokenClientArgsForCall = append(fake.preTokenClientArgsForCall, struct{}{})
	fake.recordInvocation("PreTokenClient", []interface{}{})
	fake.preTokenClientMutex.Unlock()
	if fake.PreTokenClientStub != nil {
		return fake.PreTokenClientStub()
	}
	if specificReturn {
		return ret.result1, ret.result2
	}
	return fake.preTokenClientReturns.result1, fake.preTokenClientReturns.result2
}

func (fake *FakeProvider) PreTokenClientCallCount() int {
	fake.preTokenClientMutex.RLock()
	defer fake.preTokenClientMutex.RUnlock()
	return len(fake.preTokenClientArgsForCall)
}

func (fake *FakeProvider) PreTokenClientReturns(result1 *http.Client, result2 error) {
	fake.PreTokenClientStub = nil
	fake.preTokenClientReturns = struct {
		result1 *http.Client
		result2 error
	}{result1, result2}
}

func (fake *FakeProvider) PreTokenClientReturnsOnCall(i int, result1 *http.Client, result2 error) {
	fake.PreTokenClientStub = nil
	if fake.preTokenClientReturnsOnCall == nil {
		fake.preTokenClientReturnsOnCall = make(map[int]struct {
			result1 *http.Client
			result2 error
		})
	}
	fake.preTokenClientReturnsOnCall[i] = struct {
		result1 *http.Client
		result2 error
	}{result1, result2}
}

func (fake *FakeProvider) AuthCodeURL(arg1 string, arg2 ...oauth2.AuthCodeOption) string {
	fake.authCodeURLMutex.Lock()
	ret, specificReturn := fake.authCodeURLReturnsOnCall[len(fake.authCodeURLArgsForCall)]
	fake.authCodeURLArgsForCall = append(fake.authCodeURLArgsForCall, struct {
		arg1 string
		arg2 []oauth2.AuthCodeOption
	}{arg1, arg2})
	fake.recordInvocation("AuthCodeURL", []interface{}{arg1, arg2})
	fake.authCodeURLMutex.Unlock()
	if fake.AuthCodeURLStub != nil {
		return fake.AuthCodeURLStub(arg1, arg2...)
	}
	if specificReturn {
		return ret.result1
	}
	return fake.authCodeURLReturns.result1
}

func (fake *FakeProvider) AuthCodeURLCallCount() int {
	fake.authCodeURLMutex.RLock()
	defer fake.authCodeURLMutex.RUnlock()
	return len(fake.authCodeURLArgsForCall)
}

func (fake *FakeProvider) AuthCodeURLArgsForCall(i int) (string, []oauth2.AuthCodeOption) {
	fake.authCodeURLMutex.RLock()
	defer fake.authCodeURLMutex.RUnlock()
	return fake.authCodeURLArgsForCall[i].arg1, fake.authCodeURLArgsForCall[i].arg2
}

func (fake *FakeProvider) AuthCodeURLReturns(result1 string) {
	fake.AuthCodeURLStub = nil
	fake.authCodeURLReturns = struct {
		result1 string
	}{result1}
}

func (fake *FakeProvider) AuthCodeURLReturnsOnCall(i int, result1 string) {
	fake.AuthCodeURLStub = nil
	if fake.authCodeURLReturnsOnCall == nil {
		fake.authCodeURLReturnsOnCall = make(map[int]struct {
			result1 string
		})
	}
	fake.authCodeURLReturnsOnCall[i] = struct {
		result1 string
	}{result1}
}

func (fake *FakeProvider) Exchange(arg1 context.Context, arg2 *http.Request) (*oauth2.Token, error) {
	fake.exchangeMutex.Lock()
	ret, specificReturn := fake.exchangeReturnsOnCall[len(fake.exchangeArgsForCall)]
	fake.exchangeArgsForCall = append(fake.exchangeArgsForCall, struct {
		arg1 context.Context
		arg2 *http.Request
	}{arg1, arg2})
	fake.recordInvocation("Exchange", []interface{}{arg1, arg2})
	fake.exchangeMutex.Unlock()
	if fake.ExchangeStub != nil {
		return fake.ExchangeStub(arg1, arg2)
	}
	if specificReturn {
		return ret.result1, ret.result2
	}
	return fake.exchangeReturns.result1, fake.exchangeReturns.result2
}

func (fake *FakeProvider) ExchangeCallCount() int {
	fake.exchangeMutex.RLock()
	defer fake.exchangeMutex.RUnlock()
	return len(fake.exchangeArgsForCall)
}

func (fake *FakeProvider) ExchangeArgsForCall(i int) (context.Context, *http.Request) {
	fake.exchangeMutex.RLock()
	defer fake.exchangeMutex.RUnlock()
	return fake.exchangeArgsForCall[i].arg1, fake.exchangeArgsForCall[i].arg2
}

func (fake *FakeProvider) ExchangeReturns(result1 *oauth2.Token, result2 error) {
	fake.ExchangeStub = nil
	fake.exchangeReturns = struct {
		result1 *oauth2.Token
		result2 error
	}{result1, result2}
}

func (fake *FakeProvider) ExchangeReturnsOnCall(i int, result1 *oauth2.Token, result2 error) {
	fake.ExchangeStub = nil
	if fake.exchangeReturnsOnCall == nil {
		fake.exchangeReturnsOnCall = make(map[int]struct {
			result1 *oauth2.Token
			result2 error
		})
	}
	fake.exchangeReturnsOnCall[i] = struct {
		result1 *oauth2.Token
		result2 error
	}{result1, result2}
}

func (fake *FakeProvider) Client(arg1 context.Context, arg2 *oauth2.Token) *http.Client {
	fake.clientMutex.Lock()
	ret, specificReturn := fake.clientReturnsOnCall[len(fake.clientArgsForCall)]
	fake.clientArgsForCall = append(fake.clientArgsForCall, struct {
		arg1 context.Context
		arg2 *oauth2.Token
	}{arg1, arg2})
	fake.recordInvocation("Client", []interface{}{arg1, arg2})
	fake.clientMutex.Unlock()
	if fake.ClientStub != nil {
		return fake.ClientStub(arg1, arg2)
	}
	if specificReturn {
		return ret.result1
	}
	return fake.clientReturns.result1
}

func (fake *FakeProvider) ClientCallCount() int {
	fake.clientMutex.RLock()
	defer fake.clientMutex.RUnlock()
	return len(fake.clientArgsForCall)
}

func (fake *FakeProvider) ClientArgsForCall(i int) (context.Context, *oauth2.Token) {
	fake.clientMutex.RLock()
	defer fake.clientMutex.RUnlock()
	return fake.clientArgsForCall[i].arg1, fake.clientArgsForCall[i].arg2
}

func (fake *FakeProvider) ClientReturns(result1 *http.Client) {
	fake.ClientStub = nil
	fake.clientReturns = struct {
		result1 *http.Client
	}{result1}
}

func (fake *FakeProvider) ClientReturnsOnCall(i int, result1 *http.Client) {
	fake.ClientStub = nil
	if fake.clientReturnsOnCall == nil {
		fake.clientReturnsOnCall = make(map[int]struct {
			result1 *http.Client
		})
	}
	fake.clientReturnsOnCall[i] = struct {
		result1 *http.Client
	}{result1}
}

func (fake *FakeProvider) Verify(arg1 lager.Logger, arg2 *http.Client) (bool, error) {
	fake.verifyMutex.Lock()
	ret, specificReturn := fake.verifyReturnsOnCall[len(fake.verifyArgsForCall)]
	fake.verifyArgsForCall = append(fake.verifyArgsForCall, struct {
		arg1 lager.Logger
		arg2 *http.Client
	}{arg1, arg2})
	fake.recordInvocation("Verify", []interface{}{arg1, arg2})
	fake.verifyMutex.Unlock()
	if fake.VerifyStub != nil {
		return fake.VerifyStub(arg1, arg2)
	}
	if specificReturn {
		return ret.result1, ret.result2
	}
	return fake.verifyReturns.result1, fake.verifyReturns.result2
}

func (fake *FakeProvider) VerifyCallCount() int {
	fake.verifyMutex.RLock()
	defer fake.verifyMutex.RUnlock()
	return len(fake.verifyArgsForCall)
}

func (fake *FakeProvider) VerifyArgsForCall(i int) (lager.Logger, *http.Client) {
	fake.verifyMutex.RLock()
	defer fake.verifyMutex.RUnlock()
	return fake.verifyArgsForCall[i].arg1, fake.verifyArgsForCall[i].arg2
}

func (fake *FakeProvider) VerifyReturns(result1 bool, result2 error) {
	fake.VerifyStub = nil
	fake.verifyReturns = struct {
		result1 bool
		result2 error
	}{result1, result2}
}

func (fake *FakeProvider) VerifyReturnsOnCall(i int, result1 bool, result2 error) {
	fake.VerifyStub = nil
	if fake.verifyReturnsOnCall == nil {
		fake.verifyReturnsOnCall = make(map[int]struct {
			result1 bool
			result2 error
		})
	}
	fake.verifyReturnsOnCall[i] = struct {
		result1 bool
		result2 error
	}{result1, result2}
}

func (fake *FakeProvider) Invocations() map[string][][]interface{} {
	fake.invocationsMutex.RLock()
	defer fake.invocationsMutex.RUnlock()
	fake.preTokenClientMutex.RLock()
	defer fake.preTokenClientMutex.RUnlock()
	fake.authCodeURLMutex.RLock()
	defer fake.authCodeURLMutex.RUnlock()
	fake.exchangeMutex.RLock()
	defer fake.exchangeMutex.RUnlock()
	fake.clientMutex.RLock()
	defer fake.clientMutex.RUnlock()
	fake.verifyMutex.RLock()
	defer fake.verifyMutex.RUnlock()
	copiedInvocations := map[string][][]interface{}{}
	for key, value := range fake.invocations {
		copiedInvocations[key] = value
	}
	return copiedInvocations
}

func (fake *FakeProvider) recordInvocation(key string, args []interface{}) {
	fake.invocationsMutex.Lock()
	defer fake.invocationsMutex.Unlock()
	if fake.invocations == nil {
		fake.invocations = map[string][][]interface{}{}
	}
	if fake.invocations[key] == nil {
		fake.invocations[key] = [][]interface{}{}
	}
	fake.invocations[key] = append(fake.invocations[key], args)
}

var _ provider.Provider = new(FakeProvider)
<|endoftext|>


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

// Utility functions.

package io

import (
	"bytes";
	"io";
	"os";
)

// ReadAll reads from r until an error or EOF and returns the data it read.
func ReadAll(r Reader) ([]byte, os.Error) {
	var buf bytes.Buffer;
	n, err := Copy(r, &buf);
	return buf.Data(), err;
}

// ReadFile reads the file named by filename and returns the contents.
func ReadFile(filename string) ([]byte, os.Error) {
	f, err := os.Open(filename, os.O_RDONLY, 0);
	if err != nil {
		return nil, err;
	}
	defer f.Close();
	return ReadAll(f);
}

// WriteFile writes data to a file named by filename.
// If the file does not exist, WriteFile creates it with permissions perm.
//
func WriteFile(filename string, data []byte, perm int) os.Error {
	f, err := os.Open(filename, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, perm);
	if err != nil {
		return err;
	}
	n, err := f.Write(data);
	if err == nil && n < len(data) {
		err = ErrShortWrite;
	}
	f.Close();
	return err;
}
<commit_msg>comment change<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Utility functions.

package io

import (
	"bytes";
	"io";
	"os";
)

// ReadAll reads from r until an error or EOF and returns the data it read.
func ReadAll(r Reader) ([]byte, os.Error) {
	var buf bytes.Buffer;
	n, err := Copy(r, &buf);
	return buf.Data(), err;
}

// ReadFile reads the file named by filename and returns the contents.
func ReadFile(filename string) ([]byte, os.Error) {
	f, err := os.Open(filename, os.O_RDONLY, 0);
	if err != nil {
		return nil, err;
	}
	defer f.Close();
	return ReadAll(f);
}

// WriteFile writes data to a file named by filename.
// If the file does not exist, WriteFile creates it with permissions perm;
// otherwise WriteFile truncates it before writing.
func WriteFile(filename string, data []byte, perm int) os.Error {
	f, err := os.Open(filename, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, perm);
	if err != nil {
		return err;
	}
	n, err := f.Write(data);
	if err == nil && n < len(data) {
		err = ErrShortWrite;
	}
	f.Close();
	return err;
}
<|endoftext|>


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

package os

import "syscall"

// An operating-system independent representation of Unix data structures.
// OS-specific routines in this directory convert the OS-local versions to these.

// Getpagesize returns the underlying system's memory page size.
func Getpagesize() int { return syscall.Getpagesize() }

// A FileInfo describes a file and is returned by Stat, Fstat, and Lstat
type FileInfo struct {
	Dev             uint64 // device number of file system holding file.
	Ino             uint64 // inode number.
	Nlink           uint64 // number of hard links.
	Mode            uint32 // permission and mode bits.
	Uid             int    // user id of owner.
	Gid             int    // group id of owner.
	Rdev            uint64 // device type for special file.
	Size            int64  // length in bytes.
	Blksize         int64  // size of blocks, in bytes.
	Blocks          int64  // number of blocks allocated for file.
	Atime_ns        int64  // access time; nanoseconds since epoch.
	Mtime_ns        int64  // modified time; nanoseconds since epoch.
	Ctime_ns        int64  // status change time; nanoseconds since epoch.
	Name            string // name of file as presented to Open.
	FollowedSymlink bool   // followed a symlink to get this information
}

// IsFifo reports whether the FileInfo describes a FIFO file.
func (f *FileInfo) IsFifo() bool { return (f.Mode & syscall.S_IFMT) == syscall.S_IFIFO }

// IsChar reports whether the FileInfo describes a character special file.
func (f *FileInfo) IsChar() bool { return (f.Mode & syscall.S_IFMT) == syscall.S_IFCHR }

// IsDirectory reports whether the FileInfo describes a directory.
func (f *FileInfo) IsDirectory() bool { return (f.Mode & syscall.S_IFMT) == syscall.S_IFDIR }

// IsBlock reports whether the FileInfo describes a block special file.
func (f *FileInfo) IsBlock() bool { return (f.Mode & syscall.S_IFMT) == syscall.S_IFBLK }

// IsRegular reports whether the FileInfo describes a regular file.
func (f *FileInfo) IsRegular() bool { return (f.Mode & syscall.S_IFMT) == syscall.S_IFREG }

// IsSymlink reports whether the FileInfo describes a symbolic link.
func (f *FileInfo) IsSymlink() bool { return (f.Mode & syscall.S_IFMT) == syscall.S_IFLNK }

// IsSocket reports whether the FileInfo describes a socket.
func (f *FileInfo) IsSocket() bool { return (f.Mode & syscall.S_IFMT) == syscall.S_IFSOCK }

// Permission returns the file permission bits.
func (f *FileInfo) Permission() uint32 { return f.Mode & 0777 }
<commit_msg>os: fix documentation for FileInfo.Name. It's the base name, not the full name. Fixes issue 2047.<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package os

import "syscall"

// An operating-system independent representation of Unix data structures.
// OS-specific routines in this directory convert the OS-local versions to these.

// Getpagesize returns the underlying system's memory page size.
func Getpagesize() int { return syscall.Getpagesize() }

// A FileInfo describes a file and is returned by Stat, Fstat, and Lstat
type FileInfo struct {
	Dev             uint64 // device number of file system holding file.
	Ino             uint64 // inode number.
	Nlink           uint64 // number of hard links.
	Mode            uint32 // permission and mode bits.
	Uid             int    // user id of owner.
	Gid             int    // group id of owner.
	Rdev            uint64 // device type for special file.
	Size            int64  // length in bytes.
	Blksize         int64  // size of blocks, in bytes.
	Blocks          int64  // number of blocks allocated for file.
	Atime_ns        int64  // access time; nanoseconds since epoch.
	Mtime_ns        int64  // modified time; nanoseconds since epoch.
	Ctime_ns        int64  // status change time; nanoseconds since epoch.
	Name            string // base name of the file name provided in Open, Stat, etc.
	FollowedSymlink bool   // followed a symlink to get this information
}

// IsFifo reports whether the FileInfo describes a FIFO file.
func (f *FileInfo) IsFifo() bool { return (f.Mode & syscall.S_IFMT) == syscall.S_IFIFO }

// IsChar reports whether the FileInfo describes a character special file.
func (f *FileInfo) IsChar() bool { return (f.Mode & syscall.S_IFMT) == syscall.S_IFCHR }

// IsDirectory reports whether the FileInfo describes a directory.
func (f *FileInfo) IsDirectory() bool { return (f.Mode & syscall.S_IFMT) == syscall.S_IFDIR }

// IsBlock reports whether the FileInfo describes a block special file.
func (f *FileInfo) IsBlock() bool { return (f.Mode & syscall.S_IFMT) == syscall.S_IFBLK }

// IsRegular reports whether the FileInfo describes a regular file.
func (f *FileInfo) IsRegular() bool { return (f.Mode & syscall.S_IFMT) == syscall.S_IFREG }

// IsSymlink reports whether the FileInfo describes a symbolic link.
func (f *FileInfo) IsSymlink() bool { return (f.Mode & syscall.S_IFMT) == syscall.S_IFLNK }

// IsSocket reports whether the FileInfo describes a socket.
func (f *FileInfo) IsSocket() bool { return (f.Mode & syscall.S_IFMT) == syscall.S_IFSOCK }

// Permission returns the file permission bits.
func (f *FileInfo) Permission() uint32 { return f.Mode & 0777 }
<|endoftext|>


<commit_before>package quorum

import (
	"common"
	"common/crypto"
	"common/log"
	"fmt"
	"sync"
)

type participantIndex int

// The state provides persistence to the consensus algorithms. Every participant
// should have an identical state.
type State struct {
	// a temporary overall lock, will eventually be replaced with component locks
	lock sync.Mutex

	// Network Variables
	messageSender    common.MessageSender
	participants     [common.QuorumSize]*participant // list of participants
	participantIndex participantIndex                // our participant index
	secretKey        crypto.SecretKey                // public key in our participant index

	// Heartbeat Variables
	storedEntropyStage2 common.Entropy // hashed to EntropyStage1 for previous heartbeat

	// Compile Variables
	previousEntropyStage1 [common.QuorumSize]crypto.TruncatedHash // used to verify the next round of heartbeats
	currentEntropy        common.Entropy                          // Used to generate random numbers during compilation
	upcomingEntropy       common.Entropy                          // Used to compute entropy for next block

	// Consensus Algorithm Status
	currentStep int
	ticking     bool
	tickLock    sync.Mutex
	heartbeats  [common.QuorumSize]map[crypto.TruncatedHash]*heartbeat

	// Wallet Data
	wallets map[string]uint64
}

// Only temporarily a public object, will eventually be 'type participant struct'
// makes building easier since we don't have a 'join swarm' function yet
type participant struct {
	address   common.Address
	publicKey crypto.PublicKey
}

// Create and initialize a state object
func CreateState(messageSender common.MessageSender, participantIndex participantIndex) (s State, err error) {
	// check that we have a non-nil messageSender
	if messageSender == nil {
		err = fmt.Errorf("Cannot initialize with a nil messageSender")
		return
	}

	// check that participantIndex is legal
	if int(participantIndex) >= common.QuorumSize {
		err = fmt.Errorf("Invalid participant index!")
		return
	}

	// initialize crypto keys
	pubKey, secKey, err := crypto.CreateKeyPair()
	if err != nil {
		return
	}

	// create and fill out the participant object
	self := new(participant)
	self.address = messageSender.Address()
	self.address.Id = common.Identifier(participantIndex)
	self.publicKey = pubKey

	// calculate the value of an empty hash (default for storedEntropyStage2 on all hosts is a blank array)
	emptyHash, err := crypto.CalculateTruncatedHash(s.storedEntropyStage2[:])
	if err != nil {
		return
	}

	// set state variables to their defaults
	s.messageSender = messageSender
	s.AddParticipant(self, participantIndex)
	s.secretKey = secKey
	for i := range s.previousEntropyStage1 {
		s.previousEntropyStage1[i] = emptyHash
	}
	s.participantIndex = participantIndex
	s.currentStep = 1
	s.wallets = make(map[string]uint64)

	return
}

// self() fetches the state's participant object
func (s *State) Self() (p *participant) {
	s.lock.Lock()
	defer s.lock.Unlock()
	return s.participants[s.participantIndex]
}

// add participant to s.Participants, and initialize the heartbeat map
func (s *State) AddParticipant(p *participant, i participantIndex) (err error) {
	s.lock.Lock()
	// Check that there is not already a participant for the index
	if s.participants[i] != nil {
		err = fmt.Errorf("A participant already exists for the given index!")
		return
	}
	s.participants[i] = p

	// initialize the heartbeat map for this participant
	s.heartbeats[i] = make(map[crypto.TruncatedHash]*heartbeat)
	s.lock.Unlock()

	return
}

// Use the entropy stored in the state to generate a random integer [low, high)
func (s *State) randInt(low int, high int) (randInt int, err error) {
	// verify there's a gap between the numbers
	if low == high {
		err = fmt.Errorf("low and high cannot be the same number")
		return
	}

	// Convert CurrentEntropy into an int
	rollingInt := 0
	for i := 0; i < 4; i++ {
		rollingInt = rollingInt << 4
		rollingInt += int(s.currentEntropy[0])
	}

	randInt = (rollingInt % (high - low)) + low

	// Convert random number seed to next value
	truncatedHash, err := crypto.CalculateTruncatedHash(s.currentEntropy[:])
	s.currentEntropy = common.Entropy(truncatedHash)
	return
}

func (s *State) HandleMessage(m []byte) {
	// message type is stored in the first byte, switch on this type
	switch m[0] {
	case 1:
		s.lock.Lock()
		s.handleSignedHeartbeat(m[1:])
		s.lock.Unlock()
	default:
		log.Infoln("Got message of unrecognized type")
	}
}

func (s *State) Identifier() common.Identifier {
	s.lock.Lock()
	defer s.lock.Unlock()
	return s.participants[s.participantIndex].address.Id
}

// Take an unstarted State and begin the consensus algorithm cycle
func (s *State) Start() {
	// start the ticker to progress the state
	go s.tick()

	s.lock.Lock()
	// create first heartbeat and add it to heartbeat map, then announce it
	hb, err := s.newHeartbeat()
	if err != nil {
		return
	}
	heartbeatHash, err := crypto.CalculateTruncatedHash([]byte(hb.marshal()))
	s.heartbeats[s.participantIndex][heartbeatHash] = hb
	shb, err := s.signHeartbeat(hb)
	if err != nil {
		return
	}
	s.announceSignedHeartbeat(shb)
	s.lock.Unlock()
}
<commit_msg>add consts for message types<commit_after>package quorum

import (
	"common"
	"common/crypto"
	"common/log"
	"fmt"
	"sync"
)

const (
	joinQuorumRequest       = 2
	incomingSignedHeartbeat = 1
)

type participantIndex int

// The state provides persistence to the consensus algorithms. Every participant
// should have an identical state.
type State struct {
	// a temporary overall lock, will eventually be replaced with component locks
	lock sync.Mutex

	// Network Variables
	messageSender    common.MessageSender
	participants     [common.QuorumSize]*participant // list of participants
	participantIndex participantIndex                // our participant index
	secretKey        crypto.SecretKey                // public key in our participant index

	// Heartbeat Variables
	storedEntropyStage2 common.Entropy // hashed to EntropyStage1 for previous heartbeat

	// Compile Variables
	previousEntropyStage1 [common.QuorumSize]crypto.TruncatedHash // used to verify the next round of heartbeats
	currentEntropy        common.Entropy                          // Used to generate random numbers during compilation
	upcomingEntropy       common.Entropy                          // Used to compute entropy for next block

	// Consensus Algorithm Status
	currentStep int
	ticking     bool
	tickLock    sync.Mutex
	heartbeats  [common.QuorumSize]map[crypto.TruncatedHash]*heartbeat

	// Wallet Data
	wallets map[string]uint64
}

// Only temporarily a public object, will eventually be 'type participant struct'
// makes building easier since we don't have a 'join swarm' function yet
type participant struct {
	address   common.Address
	publicKey crypto.PublicKey
}

// Create and initialize a state object
func CreateState(messageSender common.MessageSender, participantIndex participantIndex) (s State, err error) {
	// check that we have a non-nil messageSender
	if messageSender == nil {
		err = fmt.Errorf("Cannot initialize with a nil messageSender")
		return
	}

	// check that participantIndex is legal
	if int(participantIndex) >= common.QuorumSize {
		err = fmt.Errorf("Invalid participant index!")
		return
	}

	// initialize crypto keys
	pubKey, secKey, err := crypto.CreateKeyPair()
	if err != nil {
		return
	}

	// create and fill out the participant object
	self := new(participant)
	self.address = messageSender.Address()
	self.address.Id = common.Identifier(participantIndex)
	self.publicKey = pubKey

	// calculate the value of an empty hash (default for storedEntropyStage2 on all hosts is a blank array)
	emptyHash, err := crypto.CalculateTruncatedHash(s.storedEntropyStage2[:])
	if err != nil {
		return
	}

	// set state variables to their defaults
	s.messageSender = messageSender
	s.AddParticipant(self, participantIndex)
	s.secretKey = secKey
	for i := range s.previousEntropyStage1 {
		s.previousEntropyStage1[i] = emptyHash
	}
	s.participantIndex = participantIndex
	s.currentStep = 1
	s.wallets = make(map[string]uint64)

	return
}

// self() fetches the state's participant object
func (s *State) Self() (p *participant) {
	s.lock.Lock()
	defer s.lock.Unlock()
	return s.participants[s.participantIndex]
}

// add participant to s.Participants, and initialize the heartbeat map
func (s *State) AddParticipant(p *participant, i participantIndex) (err error) {
	s.lock.Lock()
	// Check that there is not already a participant for the index
	if s.participants[i] != nil {
		err = fmt.Errorf("A participant already exists for the given index!")
		return
	}
	s.participants[i] = p

	// initialize the heartbeat map for this participant
	s.heartbeats[i] = make(map[crypto.TruncatedHash]*heartbeat)
	s.lock.Unlock()

	return
}

// Use the entropy stored in the state to generate a random integer [low, high)
func (s *State) randInt(low int, high int) (randInt int, err error) {
	// verify there's a gap between the numbers
	if low == high {
		err = fmt.Errorf("low and high cannot be the same number")
		return
	}

	// Convert CurrentEntropy into an int
	rollingInt := 0
	for i := 0; i < 4; i++ {
		rollingInt = rollingInt << 4
		rollingInt += int(s.currentEntropy[0])
	}

	randInt = (rollingInt % (high - low)) + low

	// Convert random number seed to next value
	truncatedHash, err := crypto.CalculateTruncatedHash(s.currentEntropy[:])
	s.currentEntropy = common.Entropy(truncatedHash)
	return
}

func (s *State) HandleMessage(m []byte) {
	// message type is stored in the first byte, switch on this type
	switch m[0] {
	case incomingSignedHeartbeat:
		s.lock.Lock()
		s.handleSignedHeartbeat(m[1:])
		s.lock.Unlock()
	case joinQuorumRequest:
		// the message is going to contain connection information
		// will need to return a marshalled state
	default:
		log.Infoln("Got message of unrecognized type")
	}
}

func (s *State) Identifier() common.Identifier {
	s.lock.Lock()
	defer s.lock.Unlock()
	return s.participants[s.participantIndex].address.Id
}

// Take an unstarted State and begin the consensus algorithm cycle
func (s *State) Start() {
	// start the ticker to progress the state
	go s.tick()

	s.lock.Lock()
	// create first heartbeat and add it to heartbeat map, then announce it
	hb, err := s.newHeartbeat()
	if err != nil {
		return
	}
	heartbeatHash, err := crypto.CalculateTruncatedHash([]byte(hb.marshal()))
	s.heartbeats[s.participantIndex][heartbeatHash] = hb
	shb, err := s.signHeartbeat(hb)
	if err != nil {
		return
	}
	s.announceSignedHeartbeat(shb)
	s.lock.Unlock()
}
<|endoftext|>