<commit_before>// Package speed implements the "-speed" command-line option,
// similar to "openssl speed".
// It benchmarks the crypto algorithms and libraries used by
// gocryptfs.
package speed

import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"fmt"
	"log"
	"testing"

	"github.com/rfjakob/gocryptfs/internal/siv_aead"
	"github.com/rfjakob/gocryptfs/internal/stupidgcm"
)

// Run - run the speed the test and print the results.
func Run() {
	bTable := []struct {
		name      string
		f         func(*testing.B)
		preferred bool
	}{
		{name: "AES-GCM-256-OpenSSL", f: bStupidGCM, preferred: stupidgcm.PreferOpenSSL()},
		{name: "AES-GCM-256-Go", f: bGoGCM, preferred: !stupidgcm.PreferOpenSSL()},
		{name: "AES-SIV-512-Go", f: bAESSIV, preferred: false},
	}
	for _, b := range bTable {
		fmt.Printf("%-20s\t", b.name)
		mbs := mbPerSec(testing.Benchmark(b.f))
		if mbs > 0 {
			fmt.Printf("%7.2f MB/s", mbs)
		} else {
			fmt.Printf("    N/A")
		}
		if b.preferred {
			fmt.Printf("\t(selected in auto mode)\n")
		} else {
			fmt.Printf("\t\n")
		}
	}
}

func mbPerSec(r testing.BenchmarkResult) float64 {
	if r.Bytes <= 0 || r.T <= 0 || r.N <= 0 {
		return 0
	}
	return (float64(r.Bytes) * float64(r.N) / 1e6) / r.T.Seconds()
}

// Get "n" random bytes from /dev/urandom or panic
func randBytes(n int) []byte {
	b := make([]byte, n)
	_, err := rand.Read(b)
	if err != nil {
		log.Panic("Failed to read random bytes: " + err.Error())
	}
	return b
}

const blockSize = 4096

func bStupidGCM(b *testing.B) {
	if stupidgcm.BuiltWithoutOpenssl {
		b.Skip("openssl has been disabled at compile-time")
	}
	key := randBytes(32)
	authData := randBytes(24)
	iv := randBytes(16)
	in := make([]byte, blockSize)
	b.SetBytes(int64(len(in)))

	sGCM := stupidgcm.New(key, false)

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		// Encrypt and append to nonce
		sGCM.Seal(iv, iv, in, authData)
	}
}

func bGoGCM(b *testing.B) {
	key := randBytes(32)
	authData := randBytes(24)
	iv := randBytes(16)
	in := make([]byte, blockSize)
	b.SetBytes(int64(len(in)))

	gAES, err := aes.NewCipher(key)
	if err != nil {
		b.Fatal(err)
	}
	gGCM, err := cipher.NewGCMWithNonceSize(gAES, 16)
	if err != nil {
		b.Fatal(err)
	}

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		// Encrypt and append to nonce
		gGCM.Seal(iv, iv, in, authData)
	}
}

func bAESSIV(b *testing.B) {
	key := randBytes(64)
	authData := randBytes(24)
	iv := randBytes(16)
	in := make([]byte, blockSize)
	b.SetBytes(int64(len(in)))
	gGCM := siv_aead.New(key)

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		// Encrypt and append to nonce
		gGCM.Seal(iv, iv, in, authData)
	}
}
<commit_msg>speed: add code comments<commit_after>// Package speed implements the "-speed" command-line option,
// similar to "openssl speed".
// It benchmarks the crypto algorithms and libraries used by
// gocryptfs.
package speed

import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"fmt"
	"log"
	"testing"

	"github.com/rfjakob/gocryptfs/internal/siv_aead"
	"github.com/rfjakob/gocryptfs/internal/stupidgcm"
)

// 128-bit file ID + 64 bit block number = 192 bits = 24 bytes
const adLen = 24

// gocryptfs uses fixed-size 4 kiB blocks
const blockSize = 4096

// Run - run the speed the test and print the results.
func Run() {
	bTable := []struct {
		name      string
		f         func(*testing.B)
		preferred bool
	}{
		{name: "AES-GCM-256-OpenSSL", f: bStupidGCM, preferred: stupidgcm.PreferOpenSSL()},
		{name: "AES-GCM-256-Go", f: bGoGCM, preferred: !stupidgcm.PreferOpenSSL()},
		{name: "AES-SIV-512-Go", f: bAESSIV, preferred: false},
	}
	for _, b := range bTable {
		fmt.Printf("%-20s\t", b.name)
		mbs := mbPerSec(testing.Benchmark(b.f))
		if mbs > 0 {
			fmt.Printf("%7.2f MB/s", mbs)
		} else {
			fmt.Printf("    N/A")
		}
		if b.preferred {
			fmt.Printf("\t(selected in auto mode)\n")
		} else {
			fmt.Printf("\t\n")
		}
	}
}

func mbPerSec(r testing.BenchmarkResult) float64 {
	if r.Bytes <= 0 || r.T <= 0 || r.N <= 0 {
		return 0
	}
	return (float64(r.Bytes) * float64(r.N) / 1e6) / r.T.Seconds()
}

// Get "n" random bytes from /dev/urandom or panic
func randBytes(n int) []byte {
	b := make([]byte, n)
	_, err := rand.Read(b)
	if err != nil {
		log.Panic("Failed to read random bytes: " + err.Error())
	}
	return b
}

// bStupidGCM benchmarks stupidgcm's openssl GCM
func bStupidGCM(b *testing.B) {
	if stupidgcm.BuiltWithoutOpenssl {
		b.Skip("openssl has been disabled at compile-time")
	}
	key := randBytes(32)
	authData := randBytes(adLen)
	iv := randBytes(16)
	in := make([]byte, blockSize)
	b.SetBytes(int64(len(in)))

	sGCM := stupidgcm.New(key, false)

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		// Encrypt and append to nonce
		sGCM.Seal(iv, iv, in, authData)
	}
}

// bGoGCM benchmarks Go stdlib GCM
func bGoGCM(b *testing.B) {
	key := randBytes(32)
	authData := randBytes(adLen)
	iv := randBytes(16)
	in := make([]byte, blockSize)
	b.SetBytes(int64(len(in)))

	gAES, err := aes.NewCipher(key)
	if err != nil {
		b.Fatal(err)
	}
	gGCM, err := cipher.NewGCMWithNonceSize(gAES, 16)
	if err != nil {
		b.Fatal(err)
	}

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		// Encrypt and append to nonce
		gGCM.Seal(iv, iv, in, authData)
	}
}

// bAESSIV benchmarks AES-SIV from github.com/jacobsa/crypto/siv
func bAESSIV(b *testing.B) {
	key := randBytes(64)
	authData := randBytes(adLen)
	iv := randBytes(16)
	in := make([]byte, blockSize)
	b.SetBytes(int64(len(in)))
	gGCM := siv_aead.New(key)

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		// Encrypt and append to nonce
		gGCM.Seal(iv, iv, in, authData)
	}
}
<|endoftext|>


<commit_before>package piece

// Block is part of a Piece.
type Block struct {
	Index  uint32 // index in piece
	Begin  uint32 // offset in piece
	Length uint32 // always equal to BlockSize except the last block of last piece.
}
<commit_msg>fix comment<commit_after>package piece

// Block is part of a Piece.
type Block struct {
	Index  uint32 // index in piece
	Begin  uint32 // offset in piece
	Length uint32 // always equal to BlockSize except the last block of a piece.
}
<|endoftext|>


<commit_before>package store

import "time"

type MediaPlayer struct {
	ChannelTwitchId string `gorm:"primaryKey"`
	Time            float32
	CreatedAt       time.Time
	UpdatedAt       time.Time
}
<commit_msg>add media queue table<commit_after>package store

import "time"

type MediaPlayer struct {
	ChannelTwitchId string `gorm:"primaryKey"`
	Time            float32
	CreatedAt       time.Time
	UpdatedAt       time.Time
}

type MediaQueue struct {
	ChannelTwitchId string `gorm:"primaryKey"`
	Url             string
	Approved        bool
	Author          string
	Approver        string
	CreatedAt       time.Time
	UpdatedAt       time.Time
}
<|endoftext|>


<commit_before>package nsf

import (
	"errors"
	"io"
	"io/ioutil"
	"time"

	"github.com/mjibson/mog/codec/nsf/cpu6502"
)

const (
	// 1.79 MHz
	cpuClock   = 236250000 / 11 / 12
	SampleRate = 44100
)

var (
	ErrUnrecognized = errors.New("nsf: unrecognized format")
)

const (
	NSF_HEADER_LEN = 0x80
	NSF_VERSION    = 0x5
	NSF_SONGS      = 0x6
	NSF_START      = 0x7
	NSF_LOAD       = 0x8
	NSF_INIT       = 0xa
	NSF_PLAY       = 0xc
	NSF_SONG       = 0xe
	NSF_ARTIST     = 0x2e
	NSF_COPYRIGHT  = 0x4e
	NSF_SPEED_NTSC = 0x6e
	NSF_BANKSWITCH = 0x70
	NSF_SPEED_PAL  = 0x78
	NSF_PAL_NTSC   = 0x7a
	NSF_EXTRA      = 0x7b
	NSF_ZERO       = 0x7c
)

func ReadNSF(r io.Reader) (n *NSF, err error) {
	n = &NSF{}
	n.b, err = ioutil.ReadAll(r)
	if err != nil {
		return
	}
	if len(n.b) < NSF_HEADER_LEN ||
		string(n.b[0:NSF_VERSION]) != "NESM\u001a" {
		return nil, ErrUnrecognized
	}
	n.Version = n.b[NSF_VERSION]
	n.Songs = n.b[NSF_SONGS]
	n.Start = n.b[NSF_START]
	n.LoadAddr = bLEtoUint16(n.b[NSF_LOAD:])
	n.InitAddr = bLEtoUint16(n.b[NSF_INIT:])
	n.PlayAddr = bLEtoUint16(n.b[NSF_PLAY:])
	n.Song = bToString(n.b[NSF_SONG:])
	n.Artist = bToString(n.b[NSF_ARTIST:])
	n.Copyright = bToString(n.b[NSF_COPYRIGHT:])
	n.SpeedNTSC = bLEtoUint16(n.b[NSF_SPEED_NTSC:])
	copy(n.Bankswitch[:], n.b[NSF_BANKSWITCH:NSF_SPEED_PAL])
	n.SpeedPAL = bLEtoUint16(n.b[NSF_SPEED_PAL:])
	n.PALNTSC = n.b[NSF_PAL_NTSC]
	n.Extra = n.b[NSF_EXTRA]
	n.Data = n.b[NSF_HEADER_LEN:]
	return
}

type NSF struct {
	*Ram
	*cpu6502.Cpu

	b []byte // raw NSF data

	Version byte
	Songs   byte
	Start   byte

	LoadAddr uint16
	InitAddr uint16
	PlayAddr uint16

	Song      string
	Artist    string
	Copyright string

	SpeedNTSC  uint16
	Bankswitch [8]byte
	SpeedPAL   uint16
	PALNTSC    byte
	Extra      byte
	Data       []byte

	totalTicks  int64
	frameTicks  int64
	sampleTicks int64
	playTicks   int64
	samples     []float32
}

func (n *NSF) Tick() {
	n.Ram.A.Step()
	n.totalTicks++
	n.frameTicks++
	if n.frameTicks == cpuClock/240 {
		n.frameTicks = 0
		n.Ram.A.FrameStep()
	}
	n.sampleTicks++
	if n.sampleTicks >= cpuClock/SampleRate {
		n.sampleTicks = 0
		n.samples = append(n.samples, n.Ram.A.Volume())
	}
	n.playTicks++
}

func (n *NSF) Init(song byte) {
	n.Ram = new(Ram)
	n.Cpu = cpu6502.New(n.Ram)
	copy(n.Ram.M[n.LoadAddr:], n.Data)
	n.Ram.A.Init()
	n.Cpu.A = song - 1
	n.Cpu.PC = n.InitAddr
	n.Cpu.T = nil
	n.Cpu.Run()
	n.Cpu.T = n
}

func (n *NSF) Play(d time.Duration) []float32 {
	playDur := time.Duration(n.SpeedNTSC) * time.Nanosecond * 1000
	ticksPerPlay := int64(playDur / (time.Second / cpuClock))
	ticks := int64(d / (time.Second / cpuClock))
	n.samples = make([]float32, 0)
	n.totalTicks = 0
	for n.totalTicks < ticks {
		n.playTicks = 0
		n.Cpu.PC = n.PlayAddr
		n.Cpu.Halt = false
		for !n.Cpu.Halt && n.totalTicks < ticks {
			n.Cpu.Step()
		}
		for i := ticksPerPlay - n.playTicks; i > 0 && n.totalTicks < ticks; i-- {
			n.Tick()
		}
	}
	return n.samples
}

// little-endian [2]byte to uint16 conversion
func bLEtoUint16(b []byte) uint16 {
	return uint16(b[1])<<8 + uint16(b[0])
}

// null-terminated bytes to string
func bToString(b []byte) string {
	i := 0
	for i = range b {
		if b[i] == 0 {
			break
		}
	}
	return string(b[:i])
}

type Ram struct {
	M [0xffff + 1]byte
	A Apu
}

func (r *Ram) Read(v uint16) byte {
	if v == 0x4015 {
		return r.A.Read(v)
	} else {
		return r.M[v]
	}
}

func (r *Ram) Write(v uint16, b byte) {
	r.M[v] = b
	if v&0xf000 == 0x4000 {
		r.A.Write(v, b)
	}
}
<commit_msg>Panic on interrupt<commit_after>package nsf

import (
	"errors"
	"io"
	"io/ioutil"
	"time"

	"github.com/mjibson/mog/codec/nsf/cpu6502"
)

const (
	// 1.79 MHz
	cpuClock   = 236250000 / 11 / 12
	SampleRate = 44100
)

var (
	ErrUnrecognized = errors.New("nsf: unrecognized format")
)

const (
	NSF_HEADER_LEN = 0x80
	NSF_VERSION    = 0x5
	NSF_SONGS      = 0x6
	NSF_START      = 0x7
	NSF_LOAD       = 0x8
	NSF_INIT       = 0xa
	NSF_PLAY       = 0xc
	NSF_SONG       = 0xe
	NSF_ARTIST     = 0x2e
	NSF_COPYRIGHT  = 0x4e
	NSF_SPEED_NTSC = 0x6e
	NSF_BANKSWITCH = 0x70
	NSF_SPEED_PAL  = 0x78
	NSF_PAL_NTSC   = 0x7a
	NSF_EXTRA      = 0x7b
	NSF_ZERO       = 0x7c
)

func ReadNSF(r io.Reader) (n *NSF, err error) {
	n = &NSF{}
	n.b, err = ioutil.ReadAll(r)
	if err != nil {
		return
	}
	if len(n.b) < NSF_HEADER_LEN ||
		string(n.b[0:NSF_VERSION]) != "NESM\u001a" {
		return nil, ErrUnrecognized
	}
	n.Version = n.b[NSF_VERSION]
	n.Songs = n.b[NSF_SONGS]
	n.Start = n.b[NSF_START]
	n.LoadAddr = bLEtoUint16(n.b[NSF_LOAD:])
	n.InitAddr = bLEtoUint16(n.b[NSF_INIT:])
	n.PlayAddr = bLEtoUint16(n.b[NSF_PLAY:])
	n.Song = bToString(n.b[NSF_SONG:])
	n.Artist = bToString(n.b[NSF_ARTIST:])
	n.Copyright = bToString(n.b[NSF_COPYRIGHT:])
	n.SpeedNTSC = bLEtoUint16(n.b[NSF_SPEED_NTSC:])
	copy(n.Bankswitch[:], n.b[NSF_BANKSWITCH:NSF_SPEED_PAL])
	n.SpeedPAL = bLEtoUint16(n.b[NSF_SPEED_PAL:])
	n.PALNTSC = n.b[NSF_PAL_NTSC]
	n.Extra = n.b[NSF_EXTRA]
	n.Data = n.b[NSF_HEADER_LEN:]
	return
}

type NSF struct {
	*Ram
	*cpu6502.Cpu

	b []byte // raw NSF data

	Version byte
	Songs   byte
	Start   byte

	LoadAddr uint16
	InitAddr uint16
	PlayAddr uint16

	Song      string
	Artist    string
	Copyright string

	SpeedNTSC  uint16
	Bankswitch [8]byte
	SpeedPAL   uint16
	PALNTSC    byte
	Extra      byte
	Data       []byte

	totalTicks  int64
	frameTicks  int64
	sampleTicks int64
	playTicks   int64
	samples     []float32
}

func (n *NSF) Tick() {
	n.Ram.A.Step()
	n.totalTicks++
	n.frameTicks++
	if n.frameTicks == cpuClock/240 {
		n.frameTicks = 0
		n.Ram.A.FrameStep()
	}
	n.sampleTicks++
	if n.sampleTicks >= cpuClock/SampleRate {
		n.sampleTicks = 0
		n.samples = append(n.samples, n.Ram.A.Volume())
	}
	n.playTicks++
}

func (n *NSF) Init(song byte) {
	n.Ram = new(Ram)
	n.Cpu = cpu6502.New(n.Ram)
	copy(n.Ram.M[n.LoadAddr:], n.Data)
	n.Ram.A.Init()
	n.Cpu.A = song - 1
	n.Cpu.PC = n.InitAddr
	n.Cpu.T = nil
	n.Cpu.Run()
	n.Cpu.T = n
}

func (n *NSF) Play(d time.Duration) []float32 {
	playDur := time.Duration(n.SpeedNTSC) * time.Nanosecond * 1000
	ticksPerPlay := int64(playDur / (time.Second / cpuClock))
	ticks := int64(d / (time.Second / cpuClock))
	n.samples = make([]float32, 0)
	n.totalTicks = 0
	for n.totalTicks < ticks {
		n.playTicks = 0
		n.Cpu.PC = n.PlayAddr
		n.Cpu.Halt = false
		for !n.Cpu.Halt && n.totalTicks < ticks {
			n.Cpu.Step()
			if !n.Cpu.I() {
				panic("INTERRUPT")
			}
		}
		for i := ticksPerPlay - n.playTicks; i > 0 && n.totalTicks < ticks; i-- {
			n.Tick()
		}
	}
	return n.samples
}

// little-endian [2]byte to uint16 conversion
func bLEtoUint16(b []byte) uint16 {
	return uint16(b[1])<<8 + uint16(b[0])
}

// null-terminated bytes to string
func bToString(b []byte) string {
	i := 0
	for i = range b {
		if b[i] == 0 {
			break
		}
	}
	return string(b[:i])
}

type Ram struct {
	M [0xffff + 1]byte
	A Apu
}

func (r *Ram) Read(v uint16) byte {
	if v == 0x4015 {
		return r.A.Read(v)
	} else {
		return r.M[v]
	}
}

func (r *Ram) Write(v uint16, b byte) {
	r.M[v] = b
	if v&0xf000 == 0x4000 {
		r.A.Write(v, b)
	}
}
<|endoftext|>


<commit_before>package handler

import (
	"github.com/dgrijalva/jwt-go"
	"github.com/iris-contrib/middleware/cors"
	jwtmiddleware "github.com/iris-contrib/middleware/jwt"
	"github.com/iris-contrib/middleware/logger"
	"github.com/iris-contrib/middleware/recovery"
	"github.com/kataras/iris"
)

var (
	signKey = []byte("XXXXXXXXXXXXXXXX") // JWT sign key
)

// Server ...
var Server = iris.New()
var jwtmid = jwtmiddleware.New(jwtmiddleware.Config{
	ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
		return []byte(signKey), nil
	},
	SigningMethod: jwt.SigningMethodHS256,
})

func init() {
	Server.Use(cors.New(cors.Options{
		AllowedHeaders: []string{
			"Origin",
			"X-Requested-With",
			"Content-Type",
			"Accept",
			"Authorization",
		},
		AllowedMethods: []string{
			"Get",
			"Post",
			"Delete",
		},
	}))
	Server.Use(logger.New(iris.Logger))
	Server.Use(recovery.New(iris.Logger))
	Server.Post("/login", userLogin)
	Server.API("/user", userHandler{}, jwtmid.Serve)
	Server.API("/exchange", exchangeHandler{}, jwtmid.Serve)
	Server.API("/strategy", strategyHandler{}, jwtmid.Serve)
	Server.API("/trader", traderHandler{}, jwtmid.Serve)
	Server.Post("/run", jwtmid.Serve, traderRun)
	Server.Post("/stop", jwtmid.Serve, traderStop)
}
<commit_msg>fix "github.com/iris-contrib/middleware/logger" and "github.com/iris-contrib/middleware/recovery"<commit_after>package handler

import (
	"github.com/dgrijalva/jwt-go"
	"github.com/iris-contrib/middleware/cors"
	jwtmiddleware "github.com/iris-contrib/middleware/jwt"
	"github.com/iris-contrib/middleware/logger"
	"github.com/iris-contrib/middleware/recovery"
	"github.com/kataras/iris"
)

var (
	signKey = []byte("XXXXXXXXXXXXXXXX") // JWT sign key
)

// Server ...
var Server = iris.New()
var jwtmid = jwtmiddleware.New(jwtmiddleware.Config{
	ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
		return []byte(signKey), nil
	},
	SigningMethod: jwt.SigningMethodHS256,
})

func init() {
	Server.Use(cors.New(cors.Options{
		AllowedHeaders: []string{
			"Origin",
			"X-Requested-With",
			"Content-Type",
			"Accept",
			"Authorization",
		},
		AllowedMethods: []string{
			"Get",
			"Post",
			"Delete",
		},
	}))
	Server.Use(logger.New())
	Server.Use(recovery.New())
	Server.Post("/login", userLogin)
	Server.API("/user", userHandler{}, jwtmid.Serve)
	Server.API("/exchange", exchangeHandler{}, jwtmid.Serve)
	Server.API("/strategy", strategyHandler{}, jwtmid.Serve)
	Server.API("/trader", traderHandler{}, jwtmid.Serve)
	Server.Post("/run", jwtmid.Serve, traderRun)
	Server.Post("/stop", jwtmid.Serve, traderStop)
}
<|endoftext|>


<commit_before>/*
Copyright 2019 The Ceph-CSI Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package util

import (
	"errors"
	"fmt"
)

var (
	// ErrKeyNotFound is returned when requested key in omap is not found.
	ErrKeyNotFound = errors.New("key not found")
	// ErrObjectExists is returned when named omap is already present in rados.
	ErrObjectExists = errors.New("object exists")
	// ErrObjectNotFound is returned when named omap is not found in rados.
	ErrObjectNotFound = errors.New("object not found")
	// ErrSnapNameConflict is generated when a requested CSI snap name already exists on RBD but with
	// different properties, and hence is in conflict with the passed in CSI volume name.
	ErrSnapNameConflict = errors.New("snapshot name conflict")
	// ErrPoolNotFound is returned when pool is not found.
	ErrPoolNotFound = errors.New("pool not found")
	// ErrClusterIDNotSet is returned when cluster id is not set.
	ErrClusterIDNotSet = errors.New("clusterID must be set")
	// ErrMissingConfigForMonitor is returned when clusterID is not found for the mon.
	ErrMissingConfigForMonitor = errors.New("missing configuration of cluster ID for monitor")
)

type errorPair struct {
	first  error
	second error
}

func (e errorPair) Error() string {
	return fmt.Sprintf("%v: %v", e.first, e.second)
}

// Is checks if target error is wrapped in the first error.
func (e errorPair) Is(target error) bool {
	return errors.Is(e.first, target)
}

// Unwrap returns the second error.
func (e errorPair) Unwrap() error {
	return e.second
}

// JoinErrors combines two errors. Of the returned error, Is() follows the first
// branch, Unwrap() follows the second branch.
func JoinErrors(e1, e2 error) error {
	return errorPair{e1, e2}
}
<commit_msg>cleanup: rename errorPair to pairError<commit_after>/*
Copyright 2019 The Ceph-CSI Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package util

import (
	"errors"
	"fmt"
)

var (
	// ErrKeyNotFound is returned when requested key in omap is not found.
	ErrKeyNotFound = errors.New("key not found")
	// ErrObjectExists is returned when named omap is already present in rados.
	ErrObjectExists = errors.New("object exists")
	// ErrObjectNotFound is returned when named omap is not found in rados.
	ErrObjectNotFound = errors.New("object not found")
	// ErrSnapNameConflict is generated when a requested CSI snap name already exists on RBD but with
	// different properties, and hence is in conflict with the passed in CSI volume name.
	ErrSnapNameConflict = errors.New("snapshot name conflict")
	// ErrPoolNotFound is returned when pool is not found.
	ErrPoolNotFound = errors.New("pool not found")
	// ErrClusterIDNotSet is returned when cluster id is not set.
	ErrClusterIDNotSet = errors.New("clusterID must be set")
	// ErrMissingConfigForMonitor is returned when clusterID is not found for the mon.
	ErrMissingConfigForMonitor = errors.New("missing configuration of cluster ID for monitor")
)

type pairError struct {
	first  error
	second error
}

func (e pairError) Error() string {
	return fmt.Sprintf("%v: %v", e.first, e.second)
}

// Is checks if target error is wrapped in the first error.
func (e pairError) Is(target error) bool {
	return errors.Is(e.first, target)
}

// Unwrap returns the second error.
func (e pairError) Unwrap() error {
	return e.second
}

// JoinErrors combines two errors. Of the returned error, Is() follows the first
// branch, Unwrap() follows the second branch.
func JoinErrors(e1, e2 error) error {
	return pairError{e1, e2}
}
<|endoftext|>


<commit_before>package nth

import "sort"

// Element finds the nth rank ordered element and ensures it is at the nth
// position.
func Element(data sort.Interface, n int) {
	l := data.Len()
	if n < 0 || n >= l {
		return
	}
	quickSelectAdaptive(data, n, 0, l)
}

// quickSelectAdaptive is from "Fast Deterministic Selection" by Andrei
// Alexandrescu https://arxiv.org/abs/1606.00484
//
// It is deterministic O(n) selection algorithm tuned for real world
// workloads.
func quickSelectAdaptive(data sort.Interface, k, a, b int) {
	var (
		l int // |A| from the paper
		p int // pivot position
	)
	for {
		l = b - a
		r := float64(k) / float64(l) // r <- real(k) / real(|A|)
		if l < 12 {
			p = hoarePartition(data, a+l/2, a, b) // HoarePartition(A, |A| / 2)
		} else if r < 7.0/16.0 {
			if r < 1.0/12.0 {
				p = repeatedStepFarLeft(data, k, a, b)
			} else {
				p = repeatedStepLeft(data, k, a, b)
			}
		} else if r >= 1.0-7.0/16.0 {
			if r >= 1.0-1.0/12.0 {
				p = repeatedStepFarRight(data, k, a, b)
			} else {
				p = repeatedStepRight(data, k, a, b)
			}
		} else {
			p = repeatedStepImproved(data, k, a, b)
		}
		if p == k {
			return
		}
		if p > k {
			b = p // A <- A[0:p]
		} else {
			// i <- k - p - 1  // TODO what is i?
			a = p + 1 // A <- A[p+1:|A|]
		}
	}
}

func hoarePartition(data sort.Interface, p, begin, end int) int {
	data.Swap(p, begin) // Swap(A[p], A[0])
	a := begin + 1      // a = 1
	b := end - 1        // b = |A| - 1
Loop:
	for {
		for {
			if a > b {
				break Loop
			}
			if !data.Less(a, begin) { // A[a] >= A[0]
				break
			}
			a++
		}
		for data.Less(begin, b) { // A[0] < A[b]
			b--
		}
		if a >= b {
			break
		}
		data.Swap(a, b) // Swap(A[a], A[b])
		a++
		b--
	}
	data.Swap(begin, a-1) // Swap(A[0], A[a-1])
	return a - 1
}

func repeatedStepLeft(data sort.Interface, k, a, b int) int {
	l := b - a  // |A|
	if l < 12 { // |A| < 12
		return hoarePartition(data, a+l/2, a, b) // HoarePartition(A, |A| / 2)
	}
	f := l / 4                 // f <- |A| / 4
	for i := a; i < a+f; i++ { // for i <- 0 through f - 1 do
		lowerMedian4(data, i, i+f, i+2*f, i+3*f) // LowerMedian4(A, i, i+f, i+2f, i+3f)
	}
	f2 := f / 3                       // f' <- f / 3
	for i := a + f; i < a+f+f2; i++ { // for i <- f through f + f' - 1 do
		median3(data, i, i+f2, i+2*f2) // Median3(A, i, i + f', i + 2f')
	}
	newA := a + f
	quickSelect(repeatedStepLeft, data, newA+(k-a)*f2/l, newA, newA+f2)  // QuickSelect(RepeatedStepLeft, A[f:f+f'], kf'/|A|)
	return expandPartition(data, newA, newA+(k-a)*f2/l, newA+f2-1, a, b) // ExpandPartition(A, f, f + kf' / |A|, f + f' - 1)
}

func repeatedStepFarLeft(data sort.Interface, k, a, b int) int {
	l := b - a  // |A|
	if l < 12 { // |A| < 12
		return hoarePartition(data, a+l/2, a, b) // HoarePartition(A, |A| / 2)
	}
	f := l / 4                       // f <- |A| / 4
	for i := a + f; i < a+2*f; i++ { // for i <- f through 2f - 1 do
		lowerMedian4(data, i-f, i, i+f, i+2*f) // LowerMedian4(A, i - f, i, i+f, i+2f)
	}
	f2 := f / 3                       // f' <- f / 3
	for i := a + f; i < a+f+f2; i++ { // for i <- f through f + f' - 1 do
		if data.Less(i+f2, i) { // A[i + f'] < A[i]
			data.Swap(i+f2, i) // Swap(A[i + f'], A[i])
		}
		if data.Less(i+2*f2, i) { // A[i + 2f'] < A[i]
			data.Swap(i+2*f2, i) // Swap(A[i + 2f'], A[i])
		}
	}
	newA := a + f
	quickSelect(repeatedStepFarLeft, data, newA+(k-a)*f2/l, newA, newA+f2) // QuickSelect(RepeatedStepFarLeft, A[f:f+f'], kf'/|A|)
	return expandPartition(data, newA, newA+(k-a)*f2/l, newA+f2-1, a, b)   // ExpandPartition(A, f, f + kf' / |A|, f + f' - 1)
}

// lowerMedian4 takes places min at data[a] and lower median at data[b] of
// the four values data[a,b,c,d]
func lowerMedian4(data sort.Interface, a, b, c, d int) {
	// TODO is there a way to do less swaps?
	median3(data, a, b, c)
	if data.Less(d, b) {
		data.Swap(d, b)
		if data.Less(b, a) {
			data.Swap(b, a)
		}
	}
}

// median3 sorts the 3 values data[a,b,c] into the indexes a, b, c
func median3(data sort.Interface, a, b, c int) {
	if data.Less(b, a) {
		data.Swap(b, a)
	}
	if data.Less(c, b) {
		data.Swap(c, b)
		if data.Less(b, a) {
			data.Swap(b, a)
		}
	}
}

// quickSelect is the classic quickSelect with the partition function
func quickSelect(partition func(data sort.Interface, k, a, b int) int, data sort.Interface, k, a, b int) {
	for {
		p := partition(data, k, a, b) // partition(A, k)
		if p == k {
			return
		}
		if p > k {
			b = p
		} else {
			// k <- k - p - 1
			a = p + 1 // A <- A[p+1:|A|]
		}
	}
}

// expandPartition(A, a, p, b) is poorly explained in the paper. Essentially
// we want to ensure A[:a] < A[p] and A[p] < A[b:]. Luckily we can do minimal
// swaps by swaping between the two slices A[:a] and A[b:]. The tricky part is
// when we have to move the pivot such that we always have something to swap
// between A[:a] and A[b:].
func expandPartition(data sort.Interface, a, p, b, begin, end int) int {
	// Invariant: data[a:b+1] is partition around data[p]
	// Afterwards: data[begin:end] is partitioned around returned p
	i := begin
	j := end - 1
	for {
		for ; i < a && data.Less(i, p); i++ {
		}
		for ; j > b && !data.Less(j, p); j-- {
		}
		if i == a || j == b {
			break
		}
		data.Swap(i, j)
		i++
		j--
	}
	// Invariant: data[begin:i], data[a:b+1], data[j+1:end] is partitioned around p
	if i != a {
		// We still need to partition data[i:a] around p
		return hoarePartition(data, p, i, a)
	}
	if j != b {
		// We still need to partition data[b:j+1] around p
		return hoarePartition(data, p, b, j+1)
	}
	return p
}

func simplePartition(data sort.Interface, k, a, b int) int {
	p := a
	for i := a + 1; i < b; i++ {
		if data.Less(i, p) {
			data.Swap(p, i)
			p++
			data.Swap(p, i)
		}
	}
	return p
}

// TODO implement
var repeatedStepFarRight = simplePartition
var repeatedStepRight = simplePartition
var repeatedStepImproved = simplePartition
<commit_msg>typo in lowerMedian4 docstring<commit_after>package nth

import "sort"

// Element finds the nth rank ordered element and ensures it is at the nth
// position.
func Element(data sort.Interface, n int) {
	l := data.Len()
	if n < 0 || n >= l {
		return
	}
	quickSelectAdaptive(data, n, 0, l)
}

// quickSelectAdaptive is from "Fast Deterministic Selection" by Andrei
// Alexandrescu https://arxiv.org/abs/1606.00484
//
// It is deterministic O(n) selection algorithm tuned for real world
// workloads.
func quickSelectAdaptive(data sort.Interface, k, a, b int) {
	var (
		l int // |A| from the paper
		p int // pivot position
	)
	for {
		l = b - a
		r := float64(k) / float64(l) // r <- real(k) / real(|A|)
		if l < 12 {
			p = hoarePartition(data, a+l/2, a, b) // HoarePartition(A, |A| / 2)
		} else if r < 7.0/16.0 {
			if r < 1.0/12.0 {
				p = repeatedStepFarLeft(data, k, a, b)
			} else {
				p = repeatedStepLeft(data, k, a, b)
			}
		} else if r >= 1.0-7.0/16.0 {
			if r >= 1.0-1.0/12.0 {
				p = repeatedStepFarRight(data, k, a, b)
			} else {
				p = repeatedStepRight(data, k, a, b)
			}
		} else {
			p = repeatedStepImproved(data, k, a, b)
		}
		if p == k {
			return
		}
		if p > k {
			b = p // A <- A[0:p]
		} else {
			// i <- k - p - 1  // TODO what is i?
			a = p + 1 // A <- A[p+1:|A|]
		}
	}
}

func hoarePartition(data sort.Interface, p, begin, end int) int {
	data.Swap(p, begin) // Swap(A[p], A[0])
	a := begin + 1      // a = 1
	b := end - 1        // b = |A| - 1
Loop:
	for {
		for {
			if a > b {
				break Loop
			}
			if !data.Less(a, begin) { // A[a] >= A[0]
				break
			}
			a++
		}
		for data.Less(begin, b) { // A[0] < A[b]
			b--
		}
		if a >= b {
			break
		}
		data.Swap(a, b) // Swap(A[a], A[b])
		a++
		b--
	}
	data.Swap(begin, a-1) // Swap(A[0], A[a-1])
	return a - 1
}

func repeatedStepLeft(data sort.Interface, k, a, b int) int {
	l := b - a  // |A|
	if l < 12 { // |A| < 12
		return hoarePartition(data, a+l/2, a, b) // HoarePartition(A, |A| / 2)
	}
	f := l / 4                 // f <- |A| / 4
	for i := a; i < a+f; i++ { // for i <- 0 through f - 1 do
		lowerMedian4(data, i, i+f, i+2*f, i+3*f) // LowerMedian4(A, i, i+f, i+2f, i+3f)
	}
	f2 := f / 3                       // f' <- f / 3
	for i := a + f; i < a+f+f2; i++ { // for i <- f through f + f' - 1 do
		median3(data, i, i+f2, i+2*f2) // Median3(A, i, i + f', i + 2f')
	}
	newA := a + f
	quickSelect(repeatedStepLeft, data, newA+(k-a)*f2/l, newA, newA+f2)  // QuickSelect(RepeatedStepLeft, A[f:f+f'], kf'/|A|)
	return expandPartition(data, newA, newA+(k-a)*f2/l, newA+f2-1, a, b) // ExpandPartition(A, f, f + kf' / |A|, f + f' - 1)
}

func repeatedStepFarLeft(data sort.Interface, k, a, b int) int {
	l := b - a  // |A|
	if l < 12 { // |A| < 12
		return hoarePartition(data, a+l/2, a, b) // HoarePartition(A, |A| / 2)
	}
	f := l / 4                       // f <- |A| / 4
	for i := a + f; i < a+2*f; i++ { // for i <- f through 2f - 1 do
		lowerMedian4(data, i-f, i, i+f, i+2*f) // LowerMedian4(A, i - f, i, i+f, i+2f)
	}
	f2 := f / 3                       // f' <- f / 3
	for i := a + f; i < a+f+f2; i++ { // for i <- f through f + f' - 1 do
		if data.Less(i+f2, i) { // A[i + f'] < A[i]
			data.Swap(i+f2, i) // Swap(A[i + f'], A[i])
		}
		if data.Less(i+2*f2, i) { // A[i + 2f'] < A[i]
			data.Swap(i+2*f2, i) // Swap(A[i + 2f'], A[i])
		}
	}
	newA := a + f
	quickSelect(repeatedStepFarLeft, data, newA+(k-a)*f2/l, newA, newA+f2) // QuickSelect(RepeatedStepFarLeft, A[f:f+f'], kf'/|A|)
	return expandPartition(data, newA, newA+(k-a)*f2/l, newA+f2-1, a, b)   // ExpandPartition(A, f, f + kf' / |A|, f + f' - 1)
}

// lowerMedian4 places min at data[a] and lower median at data[b] of the four
// values data[a,b,c,d]
func lowerMedian4(data sort.Interface, a, b, c, d int) {
	// TODO is there a way to do less swaps?
	median3(data, a, b, c)
	if data.Less(d, b) {
		data.Swap(d, b)
		if data.Less(b, a) {
			data.Swap(b, a)
		}
	}
}

// median3 sorts the 3 values data[a,b,c] into the indexes a, b, c
func median3(data sort.Interface, a, b, c int) {
	if data.Less(b, a) {
		data.Swap(b, a)
	}
	if data.Less(c, b) {
		data.Swap(c, b)
		if data.Less(b, a) {
			data.Swap(b, a)
		}
	}
}

// quickSelect is the classic quickSelect with the partition function
func quickSelect(partition func(data sort.Interface, k, a, b int) int, data sort.Interface, k, a, b int) {
	for {
		p := partition(data, k, a, b) // partition(A, k)
		if p == k {
			return
		}
		if p > k {
			b = p
		} else {
			// k <- k - p - 1
			a = p + 1 // A <- A[p+1:|A|]
		}
	}
}

// expandPartition(A, a, p, b) is poorly explained in the paper. Essentially
// we want to ensure A[:a] < A[p] and A[p] < A[b:]. Luckily we can do minimal
// swaps by swaping between the two slices A[:a] and A[b:]. The tricky part is
// when we have to move the pivot such that we always have something to swap
// between A[:a] and A[b:].
func expandPartition(data sort.Interface, a, p, b, begin, end int) int {
	// Invariant: data[a:b+1] is partition around data[p]
	// Afterwards: data[begin:end] is partitioned around returned p
	i := begin
	j := end - 1
	for {
		for ; i < a && data.Less(i, p); i++ {
		}
		for ; j > b && !data.Less(j, p); j-- {
		}
		if i == a || j == b {
			break
		}
		data.Swap(i, j)
		i++
		j--
	}
	// Invariant: data[begin:i], data[a:b+1], data[j+1:end] is partitioned around p
	if i != a {
		// We still need to partition data[i:a] around p
		return hoarePartition(data, p, i, a)
	}
	if j != b {
		// We still need to partition data[b:j+1] around p
		return hoarePartition(data, p, b, j+1)
	}
	return p
}

func simplePartition(data sort.Interface, k, a, b int) int {
	p := a
	for i := a + 1; i < b; i++ {
		if data.Less(i, p) {
			data.Swap(p, i)
			p++
			data.Swap(p, i)
		}
	}
	return p
}

// TODO implement
var repeatedStepFarRight = simplePartition
var repeatedStepRight = simplePartition
var repeatedStepImproved = simplePartition
<|endoftext|>


<commit_before>package crawler

import (
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"strconv"

	"github.com/PuerkitoBio/goquery"
	"github.com/axgle/mahonia"
)

var (
	savePath string
)

type Article struct {
	ID       string
	Title    string
	Author   string
	Summary  string
	Category string
}

func SetSavePath(path string) {
	savePath = path
}

func GenURLs(baseURL, start, end, suffix string) []string {

	min, _ := strconv.Atoi(start)
	max, _ := strconv.Atoi(end)

	var urls []string = make([]string, 0)

	for i := min; i <= max; i++ {
		fullURL := baseURL + strconv.Itoa(i) + suffix
		urls = append(urls, fullURL)
	}

	return urls
}

func ProcessURLs(urls []string) {
	articles := []Article{}
	for index, url := range urls {
		res, err := http.Get(url)
		if err != nil {
			log.Fatal(err)
		}

		defer res.Body.Close()

		if res.StatusCode != 200 {
			log.Fatalf("status code error: %d %s", res.StatusCode, res.Status)
		}

		thisPageArticles := ProcessArticle(res.Body)
		articles = append(articles, thisPageArticles...)

		if index%5 == 0 {
			fmt.Printf("page: %v\n", index)
		}
	}
	articleBytes, _ := json.Marshal(&articles)
	// fmt.Printf("yaml: %v\n", articles)
	// fmt.Printf("json: %v\n", articleBytes)
	SavePage(strconv.Itoa(len(urls))+".tmp", articleBytes)
}

func ProcessArticle(r io.Reader) []Article {
	articles := make([]Article, 0)

	doc, err := goquery.NewDocumentFromReader(r)
	if err != nil {
		log.Fatal(err)
	}
	doc.Find(".bookinfo").Each(func(i int, s *goquery.Selection) {
		aNode := s.Find("h4 i a")
		title := ConvertToUTF8(aNode.Text())
		url, _ := aNode.Attr("href")
		id := ConvertToUTF8(ConvertToUTF8(url[9 : len(url)-5]))
		author := ConvertToUTF8(s.Find(".intro_line span").Text())
		summary := ConvertToUTF8(s.Find(".update span").Text())
		category := ConvertToUTF8(s.Find(".author").Text())

		var article = Article{id, title, author, summary, category}

		articles = append(articles, article)
	})
	return articles

}

func SavePage(name string, content []byte) {
	f, err := os.Create(savePath + string(os.PathSeparator) + name)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer f.Close()
	f.WriteString(string(content))
}

func ConvertToString(src string, srcCode string, tagCode string) string {
	srcCoder := mahonia.NewDecoder(srcCode)
	srcResult := srcCoder.ConvertString(src)
	tagCoder := mahonia.NewDecoder(tagCode)
	_, cdata, _ := tagCoder.Translate([]byte(srcResult), true)
	result := string(cdata)
	return result
}

func ConvertToUTF8(src string) string {
	return ConvertToString(src, "gbk", "utf-8")
}
<commit_msg>add request header<commit_after>package crawler

import (
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"strconv"

	"github.com/PuerkitoBio/goquery"
	"github.com/axgle/mahonia"
)

var (
	savePath string
)

type Article struct {
	ID       string
	Title    string
	Author   string
	Summary  string
	Category string
}

func SetSavePath(path string) {
	savePath = path
}

func GenURLs(baseURL, start, end, suffix string) []string {

	min, _ := strconv.Atoi(start)
	max, _ := strconv.Atoi(end)

	var urls []string = make([]string, 0)

	for i := min; i <= max; i++ {
		fullURL := baseURL + strconv.Itoa(i) + suffix
		urls = append(urls, fullURL)
	}

	return urls
}

func ProcessURLs(urls []string) {
	articles := []Article{}
	for index, url := range urls {
		res, err := MockRequest(url)
		if err != nil {
			log.Fatal(err)
		}

		defer res.Body.Close()

		if res.StatusCode != 200 {
			log.Fatalf("status code error: %d %s", res.StatusCode, res.Status)
		}

		thisPageArticles := ProcessArticle(res.Body)
		articles = append(articles, thisPageArticles...)

		if index%5 == 0 {
			fmt.Printf("page: %v\n", index)
		}
	}
	articleBytes, _ := json.Marshal(&articles)
	// fmt.Printf("yaml: %v\n", articles)
	// fmt.Printf("json: %v\n", articleBytes)
	SavePage(strconv.Itoa(len(urls))+".tmp", articleBytes)
}

func ProcessArticle(r io.Reader) []Article {
	articles := make([]Article, 0)

	doc, err := goquery.NewDocumentFromReader(r)
	if err != nil {
		log.Fatal(err)
	}
	doc.Find(".bookinfo").Each(func(i int, s *goquery.Selection) {
		aNode := s.Find("h4 i a")
		title := ConvertToUTF8(aNode.Text())
		url, _ := aNode.Attr("href")
		id := ConvertToUTF8(ConvertToUTF8(url[9 : len(url)-5]))
		author := ConvertToUTF8(s.Find(".intro_line span").Text())
		summary := ConvertToUTF8(s.Find(".update span").Text())
		category := ConvertToUTF8(s.Find(".author").Text())

		var article = Article{id, title, author, summary, category}

		articles = append(articles, article)
	})
	return articles

}

func SavePage(name string, content []byte) {
	f, err := os.Create(savePath + string(os.PathSeparator) + name)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer f.Close()
	f.WriteString(string(content))
}

func ConvertToString(src string, srcCode string, tagCode string) string {
	srcCoder := mahonia.NewDecoder(srcCode)
	srcResult := srcCoder.ConvertString(src)
	tagCoder := mahonia.NewDecoder(tagCode)
	_, cdata, _ := tagCoder.Translate([]byte(srcResult), true)
	result := string(cdata)
	return result
}

func ConvertToUTF8(src string) string {
	return ConvertToString(src, "gbk", "utf-8")
}

func MockRequest(url string) (resp *http.Response, err error) {
	client := &http.Client{}
	reqest, err := http.NewRequest("GET", url, nil)

	reqest.Header.Add("Connection", "keep-alive")
	reqest.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36")
	reqest.Header.Add("Accept-Language", "zh-CN,zh;q=0.9")

	if err != nil {
		panic(err)
	}
	return client.Do(reqest)
}
<|endoftext|>


<commit_before>// Copyright (c) 2018 Shivaram Lingamneni
// released under the MIT license

package utils

import (
	"log"
	"runtime/debug"
	"time"
)

// Semaphore is a counting semaphore. Note that a capacity of n requires O(n) storage.
// A semaphore of capacity 1 can be used as a trylock.
type Semaphore (chan bool)

// Initialize initializes a semaphore to a given capacity.
func (semaphore *Semaphore) Initialize(capacity int) {
	*semaphore = make(chan bool, capacity)
	for i := 0; i < capacity; i++ {
		(*semaphore) <- true
	}
}

// Acquire acquires a semaphore, blocking if necessary.
func (semaphore *Semaphore) Acquire() {
	<-(*semaphore)
}

// TryAcquire tries to acquire a semaphore, returning whether the acquire was
// successful. It never blocks.
func (semaphore *Semaphore) TryAcquire() (acquired bool) {
	select {
	case <-(*semaphore):
		return true
	default:
		return false
	}
}

// AcquireWithTimeout tries to acquire a semaphore, blocking for a maximum
// of approximately `d` while waiting for it. It returns whether the acquire
// was successful.
func (semaphore *Semaphore) AcquireWithTimeout(timeout time.Duration) (acquired bool) {
	if timeout < 0 {
		return semaphore.TryAcquire()
	}

	timer := time.NewTimer(timeout)
	select {
	case <-(*semaphore):
		acquired = true
	case <-timer.C:
		acquired = false
	}
	timer.Stop()
	return
}

// Release releases a semaphore. It never blocks. (This is not a license
// to program spurious releases.)
func (semaphore *Semaphore) Release() {
	select {
	case (*semaphore) <- true:
		// good
	default:
		// spurious release
		log.Printf("spurious semaphore release (full to capacity %d)", cap(*semaphore))
		debug.PrintStack()
	}
}
<commit_msg>make semaphores O(1) in storage<commit_after>// Copyright (c) 2018 Shivaram Lingamneni
// released under the MIT license

package utils

import (
	"context"
	"log"
	"runtime/debug"
	"time"
)

type e struct{}

// Semaphore is a counting semaphore.
// A semaphore of capacity 1 can be used as a trylock.
type Semaphore (chan e)

// Initialize initializes a semaphore to a given capacity.
func (semaphore *Semaphore) Initialize(capacity int) {
	*semaphore = make(chan e, capacity)
}

// Acquire acquires a semaphore, blocking if necessary.
func (semaphore *Semaphore) Acquire() {
	(*semaphore) <- e{}
}

// TryAcquire tries to acquire a semaphore, returning whether the acquire was
// successful. It never blocks.
func (semaphore *Semaphore) TryAcquire() (acquired bool) {
	select {
	case (*semaphore) <- e{}:
		return true
	default:
		return false
	}
}

// AcquireWithTimeout tries to acquire a semaphore, blocking for a maximum
// of approximately `d` while waiting for it. It returns whether the acquire
// was successful.
func (semaphore *Semaphore) AcquireWithTimeout(timeout time.Duration) (acquired bool) {
	if timeout < 0 {
		return semaphore.TryAcquire()
	}

	timer := time.NewTimer(timeout)
	select {
	case (*semaphore) <- e{}:
		acquired = true
	case <-timer.C:
		acquired = false
	}
	timer.Stop()
	return
}

// AcquireWithContext tries to acquire a semaphore, blocking at most until
// the context expires. It returns whether the acquire was successful.
// Note that if the context is already expired, the acquire may succeed anyway.
func (semaphore *Semaphore) AcquireWithContext(ctx context.Context) (acquired bool) {
	select {
	case (*semaphore) <- e{}:
		acquired = true
	case <-ctx.Done():
		acquired = false
	}
	return
}

// Release releases a semaphore. It never blocks. (This is not a license
// to program spurious releases.)
func (semaphore *Semaphore) Release() {
	select {
	case <-(*semaphore):
		// good
	default:
		// spurious release
		log.Printf("spurious semaphore release (full to capacity %d)", cap(*semaphore))
		debug.PrintStack()
	}
}
<|endoftext|>


<commit_before>package services

import (
	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/vito/cmdtest/matchers"

	. "github.com/cloudfoundry/cf-acceptance-tests/helpers/services"
	. "github.com/pivotal-cf-experimental/cf-test-helpers/cf"
	"github.com/pivotal-cf-experimental/cf-test-helpers/generator"
)

var _ = Describe("Service Broker Lifecycle", func() {
	var broker ServiceBroker

	BeforeEach(func() {
		LoginAsAdmin()
		broker = NewServiceBroker(generator.RandomName())
		broker.Push()
		broker.Configure()
	})

	AfterEach(func() {
		broker.Destroy()
		LoginAsUser()
	})

	It("confirms correct behavior in the lifecycle of a service broker", func() {
		defer Recover() // Catches panic thrown by Require expectations

		// Adding the service broker
		Require(Cf("create-service-broker", broker.Name, "username", "password", AppUri(broker.Name, ""))).To(ExitWithTimeout(0, 10*time.Second))
		Expect(Cf("service-brokers")).To(Say(broker.Name))

		// Confirming the plans are not yet public
		session := Cf("marketplace")
		Expect(session).NotTo(Say(broker.Service.Name))
		Expect(session).NotTo(Say(broker.Plan.Name))

		broker.PublicizePlans()

		// Confirming plans show up in the marketplace
		session = Cf("marketplace")
		Expect(session).To(Say(broker.Service.Name))
		Expect(session).To(Say(broker.Plan.Name))

		// Changing the catalog on the broker
		oldServiceName := broker.Service.Name
		oldPlanName := broker.Plan.Name
		broker.Service.Name = generator.RandomName()
		broker.Plan.Name = generator.RandomName()
		broker.Configure()
		Require(Cf("update-service-broker", broker.Name, "username", "password", AppUri(broker.Name, ""))).To(ExitWithTimeout(0, 10*time.Second))

		// Confirming the changes to the broker show up in the marketplace
		session = Cf("marketplace")
		Expect(session).NotTo(Say(oldServiceName))
		Expect(session).NotTo(Say(oldPlanName))
		Expect(session).To(Say(broker.Service.Name))
		Expect(session).To(Say(broker.Plan.Name))

		// Deleting the service broker and confirming the plans no longer display
		Require(Cf("delete-service-broker", broker.Name, "-f")).To(ExitWithTimeout(0, 2*time.Second))
		session = Cf("marketplace")
		Expect(session).NotTo(Say(oldServiceName))
		Expect(session).NotTo(Say(oldPlanName))
		Expect(session).NotTo(Say(broker.Service.Name))
		Expect(session).NotTo(Say(broker.Plan.Name))
	})
})
<commit_msg>Do not delete the service broker twice during tests; this causes the test to fail<commit_after>package services

import (
	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/vito/cmdtest/matchers"

	. "github.com/cloudfoundry/cf-acceptance-tests/helpers/services"
	. "github.com/pivotal-cf-experimental/cf-test-helpers/cf"
	"github.com/pivotal-cf-experimental/cf-test-helpers/generator"
)

var _ = Describe("Service Broker Lifecycle", func() {
	var broker ServiceBroker

	BeforeEach(func() {
		LoginAsAdmin()
		broker = NewServiceBroker(generator.RandomName())
		broker.Push()
		broker.Configure()
	})

	AfterEach(func() {
		LoginAsUser()
	})

	It("confirms correct behavior in the lifecycle of a service broker", func() {
		defer Recover() // Catches panic thrown by Require expectations

		// Adding the service broker
		Require(Cf("create-service-broker", broker.Name, "username", "password", AppUri(broker.Name, ""))).To(ExitWithTimeout(0, 10*time.Second))
		Expect(Cf("service-brokers")).To(Say(broker.Name))

		// Confirming the plans are not yet public
		session := Cf("marketplace")
		Expect(session).NotTo(Say(broker.Service.Name))
		Expect(session).NotTo(Say(broker.Plan.Name))

		broker.PublicizePlans()

		// Confirming plans show up in the marketplace
		session = Cf("marketplace")
		Expect(session).To(Say(broker.Service.Name))
		Expect(session).To(Say(broker.Plan.Name))

		// Changing the catalog on the broker
		oldServiceName := broker.Service.Name
		oldPlanName := broker.Plan.Name
		broker.Service.Name = generator.RandomName()
		broker.Plan.Name = generator.RandomName()
		broker.Configure()
		Require(Cf("update-service-broker", broker.Name, "username", "password", AppUri(broker.Name, ""))).To(ExitWithTimeout(0, 10*time.Second))

		// Confirming the changes to the broker show up in the marketplace
		session = Cf("marketplace")
		Expect(session).NotTo(Say(oldServiceName))
		Expect(session).NotTo(Say(oldPlanName))
		Expect(session).To(Say(broker.Service.Name))
		Expect(session).To(Say(broker.Plan.Name))

		// Deleting the service broker and confirming the plans no longer display
		Require(Cf("delete-service-broker", broker.Name, "-f")).To(ExitWithTimeout(0, 2*time.Second))
		session = Cf("marketplace")
		Expect(session).NotTo(Say(oldServiceName))
		Expect(session).NotTo(Say(oldPlanName))
		Expect(session).NotTo(Say(broker.Service.Name))
		Expect(session).NotTo(Say(broker.Plan.Name))

		Require(Cf("delete", b.Name, "-f")).To(ExitWithTimeout(0, 2*time.Second))
	})
})
<|endoftext|>


<commit_before>// Package push sends notifications over HTTP/2 to
// Apple's Push Notification Service.
package push

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"strconv"
	"time"
)

// Apple host locations.
const (
	Sandbox = "https://api.sandbox.push.apple.com"
	Live    = "https://api.push.apple.com"
)

// Service is the Apple Push Notification Service that you send notifications to.
type Service struct {
	Client *http.Client
	Host   string
}

// Headers sent with a push to control the notification (optional)
type Headers struct {
	// ID for the notification. Apple generates one if ommitted.
	// This should be a UUID with 32 lowercase hexadecimal digits.
	// TODO: use a UUID type.
	ID string

	// Apple will retry delivery until this time. The default behavior only tries once.
	Expiration time.Time

	// Allow Apple to group messages to together to reduce power consumption.
	// By default messages are sent immediately.
	LowPriority bool

	// Topic for certificates with multiple topics.
	Topic string
}

// Service error responses.
var (
	ErrBadDeviceToken = errors.New("bad device token")
	ErrForbidden      = errors.New("forbidden, check your certificate")
)

type response struct {
	// Reason for failure
	Reason string `json:"reason"`
	// Timestamp for 410 errors (maybe this is an int)
	Timestamp string `json:"timestamp"`
}

// Push notification to APN service after performing serialization.
func (s *Service) Push(deviceToken string, headers *Headers, payload json.Marshaler) (string, error) {
	b, err := json.Marshal(payload)
	if err != nil {
		return "", err
	}
	return s.PushBytes(deviceToken, headers, b)
}

// PushBytes notification to APN service.
func (s *Service) PushBytes(deviceToken string, headers *Headers, payload []byte) (string, error) {
	urlStr := fmt.Sprintf("%v/3/device/%v", s.Host, deviceToken)

	req, err := http.NewRequest("POST", urlStr, bytes.NewReader(payload))
	if err != nil {
		return "", err
	}
	req.Header.Set("Content-Type", "application/json")
	headers.set(req)

	resp, err := s.Client.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	if resp.StatusCode == http.StatusOK {
		return resp.Header.Get("apns-id"), nil
	}

	// read entire response body
	// TODO: could decode while reading instead
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	var response response
	json.Unmarshal(body, &response)

	switch response.Reason {
	case "BadDeviceToken":
		return "", ErrBadDeviceToken
	case "Forbidden":
		return "", ErrForbidden
	}
	return "", fmt.Errorf("Error response: %v", response.Reason)
}

// set headers on an HTTP request
func (h *Headers) set(req *http.Request) {
	// headers are optional
	if h == nil {
		return
	}

	if h.ID != "" {
		req.Header.Set("apns-id", h.ID)
	} // when ommitted, Apple will generate a UUID for you

	if !h.Expiration.IsZero() {
		req.Header.Set("apns-expiration", strconv.FormatInt(h.Expiration.Unix(), 10))
	}

	if h.LowPriority {
		req.Header.Set("apns-priority", "5")
	} // when ommitted, the default priority is 10

	if h.Topic != "" {
		req.Header.Set("apns-topic", h.Topic)
	}
}
<commit_msg>service: handle other error reasons from Apple<commit_after>// Package push sends notifications over HTTP/2 to
// Apple's Push Notification Service.
package push

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"strconv"
	"time"
)

// Apple host locations.
const (
	Sandbox = "https://api.sandbox.push.apple.com"
	Live    = "https://api.push.apple.com"
)

// Service is the Apple Push Notification Service that you send notifications to.
type Service struct {
	Client *http.Client
	Host   string
}

// Headers sent with a push to control the notification (optional)
type Headers struct {
	// ID for the notification. Apple generates one if ommitted.
	// This should be a UUID with 32 lowercase hexadecimal digits.
	// TODO: use a UUID type.
	ID string

	// Apple will retry delivery until this time. The default behavior only tries once.
	Expiration time.Time

	// Allow Apple to group messages to together to reduce power consumption.
	// By default messages are sent immediately.
	LowPriority bool

	// Topic for certificates with multiple topics.
	Topic string
}

// Service error responses.
var (
	// These could be checked prior to sending the request to Apple.

	ErrPayloadEmpty    = errors.New("the message payload was empty")
	ErrPayloadTooLarge = errors.New("the message payload was too large")

	// Device token errors.

	ErrMissingDeviceToken = errors.New("device token was not specified")
	ErrBadDeviceToken     = errors.New("bad device token")
	ErrTooManyRequests    = errors.New("too many requests were made consecutively to the same device token")

	// Header errors.

	ErrBadMessageID      = errors.New("the ID header value is bad")
	ErrBadExpirationDate = errors.New("the Expiration header value is bad")
	ErrBadPriority       = errors.New("the apns-priority value is bad")
	ErrBadTopic          = errors.New("the Topic header was invalid")

	// Certificate and topic errors.

	ErrBadCertificate            = errors.New("the certificate was bad")
	ErrBadCertificateEnvironment = errors.New("certificate was for the wrong environment")
	ErrForbidden                 = errors.New("there was an error with the certificate")

	ErrMissingTopic           = errors.New("the Topic header of the request was not specified and was required")
	ErrTopicDisallowed        = errors.New("pushing to this topic is not allowed")
	ErrUnregistered           = errors.New("device token is inactive for the specified topic")
	ErrDeviceTokenNotForTopic = errors.New("device token does not match the specified topic")

	// These errros should never happen when using Push.

	ErrDuplicateHeaders = errors.New("one or more headers were repeated")
	ErrBadPath          = errors.New("the request contained a bad :path")
	ErrMethodNotAllowed = errors.New("the specified :method was not POST")

	// Fatal server errors.

	ErrIdleTimeout         = errors.New("idle time out")
	ErrShutdown            = errors.New("the server is shutting down")
	ErrInternalServerError = errors.New("an internal server error occurred")
	ErrServiceUnavailable  = errors.New("the service is unavailable")

	// HTTP Status errors.

	ErrBadRequest = errors.New("bad request")
	ErrGone       = errors.New("the device token is no longer active for the topic")
	ErrUnknown    = errors.New("unknown error")
)

var errorReason = map[string]error{
	"PayloadEmpty":              ErrPayloadEmpty,
	"PayloadTooLarge":           ErrPayloadTooLarge,
	"BadTopic":                  ErrBadTopic,
	"TopicDisallowed":           ErrTopicDisallowed,
	"BadMessageId":              ErrBadMessageID,
	"BadExpirationDate":         ErrBadExpirationDate,
	"BadPriority":               ErrBadPriority,
	"MissingDeviceToken":        ErrMissingDeviceToken,
	"BadDeviceToken":            ErrBadDeviceToken,
	"DeviceTokenNotForTopic":    ErrDeviceTokenNotForTopic,
	"Unregistered":              ErrUnregistered,
	"DuplicateHeaders":          ErrDuplicateHeaders,
	"BadCertificateEnvironment": ErrBadCertificateEnvironment,
	"BadCertificate":            ErrBadCertificate,
	"Forbidden":                 ErrForbidden,
	"BadPath":                   ErrBadPath,
	"MethodNotAllowed":          ErrMethodNotAllowed,
	"TooManyRequests":           ErrTooManyRequests,
	"IdleTimeout":               ErrIdleTimeout,
	"Shutdown":                  ErrShutdown,
	"InternalServerError":       ErrInternalServerError,
	"ServiceUnavailable":        ErrServiceUnavailable,
	"MissingTopic":              ErrMissingTopic,
}

type response struct {
	// Reason for failure
	Reason string `json:"reason"`
	// Timestamp for 410 errors (maybe this is an int)
	Timestamp string `json:"timestamp"`
}

const statusTooManyRequests = 429

// Push notification to APN service after performing serialization.
func (s *Service) Push(deviceToken string, headers *Headers, payload json.Marshaler) (string, error) {
	b, err := json.Marshal(payload)
	if err != nil {
		return "", err
	}
	return s.PushBytes(deviceToken, headers, b)
}

// PushBytes notification to APN service.
func (s *Service) PushBytes(deviceToken string, headers *Headers, payload []byte) (string, error) {
	urlStr := fmt.Sprintf("%v/3/device/%v", s.Host, deviceToken)

	req, err := http.NewRequest("POST", urlStr, bytes.NewReader(payload))
	if err != nil {
		return "", err
	}
	req.Header.Set("Content-Type", "application/json")
	headers.set(req)

	resp, err := s.Client.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	if resp.StatusCode == http.StatusOK {
		return resp.Header.Get("apns-id"), nil
	}

	// read entire response body
	// TODO: could decode while reading instead
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	var response response
	json.Unmarshal(body, &response)

	if e, ok := errorReason[response.Reason]; ok {
		return "", e
	}

	// fallback to HTTP status codes if reason not found in JSON

	switch resp.StatusCode {
	case http.StatusBadRequest:
		return "", ErrBadRequest
	case http.StatusForbidden:
		return "", ErrForbidden
	case http.StatusMethodNotAllowed:
		return "", ErrMethodNotAllowed
	case http.StatusGone:
		// TODO: this should return an error structure with timestamp
		// but I don't know the format of timestamp (Unix time?)
		// and there may be a JSON response handled above (ErrUnregistered?)
		return "", ErrGone
	case http.StatusRequestEntityTooLarge:
		return "", ErrPayloadTooLarge
	case statusTooManyRequests:
		return "", ErrTooManyRequests
	case http.StatusInternalServerError:
		return "", ErrInternalServerError
	case http.StatusServiceUnavailable:
		return "", ErrServiceUnavailable
	}

	return "", ErrUnknown
}

// set headers on an HTTP request
func (h *Headers) set(req *http.Request) {
	// headers are optional
	if h == nil {
		return
	}

	if h.ID != "" {
		req.Header.Set("apns-id", h.ID)
	} // when ommitted, Apple will generate a UUID for you

	if !h.Expiration.IsZero() {
		req.Header.Set("apns-expiration", strconv.FormatInt(h.Expiration.Unix(), 10))
	}

	if h.LowPriority {
		req.Header.Set("apns-priority", "5")
	} // when ommitted, the default priority is 10

	if h.Topic != "" {
		req.Header.Set("apns-topic", h.Topic)
	}
}
<|endoftext|>


<commit_before>package hhsuite

import (
	"io/ioutil"
	"os"
	"runtime"

	"github.com/BurntSushi/cmd"

	"github.com/BurntSushi/bcbgo/io/hhr"
)

type HHBlitsConfig struct {
	Exec       string
	CPUs       int
	Iterations int
	MAct       float64
	OutA3M     string
}

var HHBlitsDefault = HHBlitsConfig{
	Exec:       "hhblits",
	CPUs:       runtime.NumCPU(),
	Iterations: 2,
	MAct:       0.35,
	OutA3M:     "",
}

// Run will execute HHblits using the given configuration, database and query
// file path. The query can be a path to a fasta file, A3M file or HHM file.
// (As per the '-i' flag for hhblits.)
func (conf HHBlitsConfig) Run(db Database, query string) (*hhr.HHR, error) {
	hhrFile, err := ioutil.TempFile("", "bcbgo-hhr")
	if err != nil {
		return nil, err
	}
	defer os.Remove(hhrFile.Name())

	args := []string{
		"-cpu", fmt.Sprintf("%d", conf.CPUs),
		"-i", query,
		"-d", db.Resolve(),
		"-n", conf.Iterations,
		"-mact", fmt.Sprintf("%f", conf.MAct),
		"-o", hhrFile.Name(),
	}
	if len(conf.OutA3M) > 0 {
		args = append(args, []string{"-oa3m", conf.OutA3M}...)
	}
	err = cmd.New(conf.Path, args...).Run()
	if err != nil {
		return nil, err
	}

	results, err := hhr.Read(hhrFile)
	if err != nil {
		return nil, err
	}
	return results, nil
}
<commit_msg>It'd be nice if I committed code that compiled.<commit_after>package hhsuite

import (
	"fmt"
	"io/ioutil"
	"os"
	"runtime"

	"github.com/BurntSushi/cmd"

	"github.com/BurntSushi/bcbgo/io/hhr"
)

type HHBlitsConfig struct {
	Exec       string
	CPUs       int
	Iterations int
	MAct       float64
	OutA3M     string
}

var HHBlitsDefault = HHBlitsConfig{
	Exec:       "hhblits",
	CPUs:       runtime.NumCPU(),
	Iterations: 2,
	MAct:       0.35,
	OutA3M:     "",
}

// Run will execute HHblits using the given configuration, database and query
// file path. The query can be a path to a fasta file, A3M file or HHM file.
// (As per the '-i' flag for hhblits.)
func (conf HHBlitsConfig) Run(db Database, query string) (*hhr.HHR, error) {
	hhrFile, err := ioutil.TempFile("", "bcbgo-hhr")
	if err != nil {
		return nil, err
	}
	defer os.Remove(hhrFile.Name())

	args := []string{
		"-cpu", fmt.Sprintf("%d", conf.CPUs),
		"-i", query,
		"-d", db.Resolve(),
		"-n", fmt.Sprintf("%d", conf.Iterations),
		"-mact", fmt.Sprintf("%f", conf.MAct),
		"-o", hhrFile.Name(),
	}
	if len(conf.OutA3M) > 0 {
		args = append(args, []string{"-oa3m", conf.OutA3M}...)
	}
	err = cmd.New(conf.Exec, args...).Run()
	if err != nil {
		return nil, err
	}

	results, err := hhr.Read(hhrFile)
	if err != nil {
		return nil, err
	}
	return results, nil
}
<|endoftext|>


<commit_before>package main

func init() {
	println("main/z: top init")
}

func init() {
	println("main/z: bottom init")
}
<commit_msg>initfuncs: add setGlobal to z<commit_after>package main

func init() {
	println("main/z: top init")
	setGlobal("zit")
}

func init() {
	println("main/z: bottom init")
	setGlobal("zib")
}
<|endoftext|>


<commit_before>package golang

import (
	"path/filepath"

	"sourcegraph.com/sourcegraph/srcgraph/unit"
)

func init() {
	unit.Register("GoPackage", &Package{})
}

type Package struct {
	Dir        string `toml:"dir"`
	ImportPath string `toml:"import_path"`
	Files      []string
}

func (p Package) Name() string    { return p.Dir }
func (p Package) RootDir() string { return p.Dir }
func (p Package) Paths() []string { return []string{filepath.Join(p.Dir, "*.go")} }
<commit_msg>go package Paths returns actual files, not glob<commit_after>package golang

import (
	"path/filepath"

	"sourcegraph.com/sourcegraph/srcgraph/unit"
)

func init() {
	unit.Register("GoPackage", &Package{})
}

type Package struct {
	Dir        string `toml:"dir"`
	ImportPath string `toml:"import_path"`
	Files      []string
}

func (p Package) Name() string    { return p.Dir }
func (p Package) RootDir() string { return p.Dir }
func (p Package) Paths() []string {
	paths := make([]string, len(p.Files))
	for i, f := range p.Files {
		paths[i] = filepath.Join(p.Dir, f)
	}
	return paths
}
<|endoftext|>


<commit_before>// Package ode provides the Euler-Forward and Runge-Kutta
// Method for solving ordinary differential equations.
package ode

import "fmt"

// BUG(sj14): The Runge-Kutta Method doesn't seem to work properly (not precise)

func EulerForward(from, h, to, t float64, y []float64, fn func(float64, []float64) []float64) [][]float64 {
	var steps int = int(to - from/h)
	var parameters = len(y)

	fmt.Println(steps)
	fmt.Println(parameters)

	// initialize 'outer slice'
	ySlice := make([][]float64, steps)
	// initialize first 'inner slice'
	ySlice[0] = make([]float64, parameters+1)

	// fill with start values
	for i := 0; i < parameters; i++ {
		ySlice[0][i+1] = y[i]
	}

	for step := 1; step < steps; step++ {
		t += h
		// initialize 'inner slice'
		ySlice[step] = make([]float64, parameters+1)
		ySlice[step][0] = t

		for value := 0; value < parameters; value++ {
			y[value] += h * fn(t, y)[value]
			ySlice[step][value+1] = y[value]
		}
	}
	return ySlice
}

func RungeKutta(from, h, to, t float64, y []float64, fn func(float64, []float64) []float64) [][]float64 {
	var steps int = int(to - from/h)
	var parameters = len(y)

	fmt.Println(steps)
	fmt.Println(parameters)

	// initialize 'outer slice'
	ySlice := make([][]float64, steps)
	// initialize first 'inner slice'
	ySlice[0] = make([]float64, parameters+1)

	// fill with start values
	for i := 0; i < parameters; i++ {
		ySlice[0][i+1] = y[i]
	}

	var k1 []float64 = make([]float64, parameters)
	var k2 []float64 = make([]float64, parameters)
	var k3 []float64 = make([]float64, parameters)
	var k4 []float64 = make([]float64, parameters)

	for step := 1; step < steps; step++ {
		// initialize 'inner slice'
		ySlice[step] = make([]float64, parameters+1)

		// TODO At the begin or end of the loop????
		for value := 0; value < parameters; value++ {
			y[value] += h * fn(t, y)[value]
		}

		for value := 0; value < parameters; value++ {
			k1[value] = h * 0.5 * fn(t, y)[value]
		}

		t += h / 2

		for value := 0; value < parameters; value++ {
			k2[value] = h * 0.5 * fn(t, k1)[value]
		}

		for value := 0; value < parameters; value++ {
			k3[value] = h * fn(t, k2)[value]
		}

		t += h / 2

		for value := 0; value < parameters; value++ {
			k4[value] = h * fn(t, k3)[value]
		}

		ySlice[step][0] = t

		for value := 0; value < parameters; value++ {
			ySlice[step][value+1] = y[value] + (k1[value]+2*k2[value]+2*k3[value]+k4[value])/6
		}
	}
	return ySlice
}
<commit_msg>fixed runge-kutta method<commit_after>// Package ode provides the Euler-Forward and Runge-Kutta
// Method for solving ordinary differential equations.
package ode

import "fmt"

func EulerForward(from, h, to, t float64, y []float64, fn func(float64, []float64) []float64) [][]float64 {
	var steps int = int(to - from/h)
	var parameters = len(y)

	fmt.Println(steps)
	fmt.Println(parameters)

	// initialize 'outer slice'
	ySlice := make([][]float64, steps)
	// initialize first 'inner slice'
	ySlice[0] = make([]float64, parameters+1)

	// fill with start values
	for i := 0; i < parameters; i++ {
		ySlice[0][i+1] = y[i]
	}

	for step := 1; step < steps; step++ {
		t += h
		// initialize 'inner slice'
		ySlice[step] = make([]float64, parameters+1)
		ySlice[step][0] = t

		for value := 0; value < parameters; value++ {
			y[value] += h * fn(t, y)[value]
			ySlice[step][value+1] = y[value]
		}
	}
	return ySlice
}

func RungeKutta(from, h, to, t float64, y []float64, fn func(float64, []float64) []float64) [][]float64 {
	var steps int = int(to - from/h)
	var parameters = len(y)

	fmt.Println(steps)
	fmt.Println(parameters)

	// initialize 'outer slice'
	ySlice := make([][]float64, steps)
	// initialize first 'inner slice'
	ySlice[0] = make([]float64, parameters+1)

	// fill with start values
	for i := 0; i < parameters; i++ {
		ySlice[0][i+1] = y[i]
	}

	var k1 []float64 = make([]float64, parameters)
	var k2 []float64 = make([]float64, parameters)
	var k3 []float64 = make([]float64, parameters)
	var k4 []float64 = make([]float64, parameters)

	var yn []float64 = make([]float64, parameters)

	// the parameters to pass into the corresponding function calls
	var k2p []float64 = make([]float64, parameters)
	var k3p []float64 = make([]float64, parameters)
	var k4p []float64 = make([]float64, parameters)

	for step := 1; step < steps; step++ {
		// initialize 'inner slice'
		ySlice[step] = make([]float64, parameters+1)

		// get last yn from the slice to make the rest of the function shorter
		for value := 0; value < parameters; value++ {
			yn[value] = ySlice[step-1][value+1]
		}

		// generate k1
		for value := 0; value < parameters; value++ {
			k1[value] = fn(t, yn)[value]
		}

		t += h / 2

		// generate the parameter for k2
		for value := 0; value < parameters; value++ {
			k2p[value] = yn[value] + 0.5 * k1[value]
		}

		// generate k2
		for value := 0; value < parameters; value++ {
			k2[value] = fn(t, k2p)[value]
		}

		// generate the parameter for k3
		for value := 0; value < parameters; value++ {
			k3p[value] = yn[value] + 0.5 * k2[value]
		}

		// generate k3
		for value := 0; value < parameters; value++ {
			k3[value] = fn(t, k3p)[value]
		}

		// generate the parameter for k4
		for value := 0; value < parameters; value++ {
			k4p[value] = yn[value] + fn(t, k3p)[value]
		}

		t += h / 2

		// generate k4
		for value := 0; value < parameters; value++ {
			k4[value] = fn(t, k4p)[value]
		}

		ySlice[step][0] = t

		// generate yn (saved in the slice)
		for value := 0; value < parameters; value++ {
			ySlice[step][value+1] = ySlice[step-1][value+1] + (k1[value]+2*k2[value]+2*k3[value]+k4[value])/6.0
		}
	}
	return ySlice
}
<|endoftext|>


<commit_before>package brokerage_server_ib

import (
	"context"
	"sync"
	"time"

	"github.com/dimfeld/ib"
)

func (p *IB) getLatestHistData(ctx context.Context, contract *ib.Contract, histTypes []ib.HistDataToShow) ([]*ib.HistoricalData, error) {

	wg := sync.WaitGroup{}
	histDataItems := make([]*ib.HistoricalData, len(histTypes))
	histDataErrors := make([]error, len(histTypes))
	wg.Add(len(histTypes))

	// Get a single bar for each historical data item. We do this because the IB
	// streaming data isn't always reliable, especially after hours.
	now := time.Now()
	for i, histType := range histTypes {
		go func(i int, histType ib.HistDataToShow) {
			defer wg.Done()
			req := ib.RequestHistoricalData{
				Contract:    *contract,
				EndDateTime: now,
				Duration:    "60 S",
				// Use 1 minute bars to avoid hitting IB's pacing restrictions.
				BarSize:    ib.HistBarSize1Min,
				WhatToShow: histType,
				UseRTH:     true,
			}

			histDataItems[i], histDataErrors[i] = p.historicalData(ctx, &req)
		}(i, histType)
	}

	wg.Wait()
	var err error
	for i, e := range histDataErrors {
		if e != nil {
			p.Logger.Error("Historical data error",
				"type", histTypes[i],
				"error", e.Error())
			err = e
		}
	}

	return histDataItems, err
}

func (p *IB) historicalData(ctx context.Context, req *ib.RequestHistoricalData) (*ib.HistoricalData, error) {

	var output *ib.HistoricalData
	_, err := p.syncMatchedRequest(ctx, req, func(r ib.Reply) (replyBehavior, error) {
		switch data := r.(type) {
		case *ib.ErrorMessage:
			return REPLY_DONE, data.Error()
		case *ib.HistoricalData:
			output = data
			return REPLY_DONE, nil
		default:
			p.Logger.Warn("HistoricalData: unexpected reply", "msg", r)
		}

		return REPLY_CONTINUE, nil
	})

	return output, err
}

// func (p *IB) GetHistoricalData(ctx context.Context, params types.HistoricalDataParams) ()
<commit_msg>Support for retrieving historical price, IV, HV data<commit_after>package brokerage_server_ib

import (
	"context"
	"sync"
	"time"

	"github.com/dimfeld/brokerage_server/types"
	"github.com/dimfeld/ib"
)

func (p *IB) getLatestHistData(ctx context.Context, contract *ib.Contract, histTypes []ib.HistDataToShow) ([]*ib.HistoricalData, error) {

	wg := sync.WaitGroup{}
	histDataItems := make([]*ib.HistoricalData, len(histTypes))
	histDataErrors := make([]error, len(histTypes))
	wg.Add(len(histTypes))

	// Get a single bar for each historical data item. We do this because the IB
	// streaming data isn't always reliable, especially after hours.
	now := time.Now()
	for i, histType := range histTypes {
		go func(i int, histType ib.HistDataToShow) {
			defer wg.Done()
			req := ib.RequestHistoricalData{
				Contract:    *contract,
				EndDateTime: now,
				Duration:    "60 S",
				// Use 1 minute bars to avoid hitting IB's pacing restrictions.
				BarSize:    ib.HistBarSize1Min,
				WhatToShow: histType,
				UseRTH:     true,
			}

			histDataItems[i], histDataErrors[i] = p.oneHistoricalData(ctx, &req)
		}(i, histType)
	}

	wg.Wait()
	var err error
	for i, e := range histDataErrors {
		if e != nil {
			p.Logger.Error("Historical data error",
				"type", histTypes[i],
				"error", e.Error())
			err = e
		}
	}

	return histDataItems, err
}

func (p *IB) oneHistoricalData(ctx context.Context, req *ib.RequestHistoricalData) (*ib.HistoricalData, error) {

	var output *ib.HistoricalData
	_, err := p.syncMatchedRequest(ctx, req, func(r ib.Reply) (replyBehavior, error) {
		switch data := r.(type) {
		case *ib.ErrorMessage:
			return REPLY_DONE, data.Error()
		case *ib.HistoricalData:
			output = data
			return REPLY_DONE, nil
		default:
			p.Logger.Warn("HistoricalData: unexpected reply", "msg", r)
		}

		return REPLY_CONTINUE, nil
	})

	return output, err
}

func (p *IB) GetHistoricalData(ctx context.Context, params types.HistoricalDataParams) ([]*types.Quote, error) {

	which := params.Which
	var dataType ib.HistDataToShow
	switch params.Which {
	default:
		which = types.HistoricalDataTypePrice
		fallthrough
	case types.HistoricalDataTypePrice:
		dataType = ib.HistTrades
	case types.HistoricalDataTypeIv:
		dataType = ib.HistOptionIV
	case types.HistoricalDataTypeHv:
		dataType = ib.HistVolatility

	}

	if params.Symbol != "" && dataType != ib.HistTrades {
		return nil, types.ArgError("options historical quotes must be for price data")
	}

	var key ContractKey
	if params.Symbol != "" {
		key = ContractKey{
			Symbol:       params.Symbol,
			SecurityType: "STK",
		}
	} else {
		key = ContractKeyFromOption(&params.Option)
	}
	details, err := p.contractManager.GetContractDetails(ctx, key)
	if err != nil {
		return nil, err
	} else if len(details) == 0 {
		return nil, types.ArgError("Contract not found")
	}

	// Get an estimate of the proper array size.
	totalBars := params.Duration / params.BarWidth
	output := make([]*types.Quote, 0, totalBars)

	req := &ib.RequestHistoricalData{
		Contract:    details[0].Summary,
		EndDateTime: params.EndTime,
		WhatToShow:  dataType,
		Duration:    durationToIbDuration(params.Duration),
		BarSize:     durationToBarWidth(params.BarWidth),
		UseRTH:      !params.IncludeAH,
	}

	_, err = p.syncMatchedRequest(ctx, req, func(r ib.Reply) (replyBehavior, error) {
		switch data := r.(type) {
		case *ib.ErrorMessage:
			return REPLY_DONE, data.Error()
		case *ib.HistoricalData:
			for i, _ := range data.Data {
				item := &data.Data[i]
				quote := &types.Quote{
					High:   item.High,
					Low:    item.Low,
					Open:   item.Open,
					Close:  item.Close,
					Volume: item.Volume,
				}

				if which == types.HistoricalDataTypeHv {
					quote.OptionHistoricalVolatility = item.Close
				} else if which == types.HistoricalDataTypeIv {
					quote.OptionImpliedVolatility = item.Close
				}
				output = append(output, quote)
			}

			return REPLY_DONE, nil
		default:
			p.Logger.Warn("HistoricalData: unexpected reply", "msg", r)
		}

		return REPLY_CONTINUE, nil
	})

	return output, nil
}
<|endoftext|>


<commit_before>package iotool

import(
	"math/rand"
	"os"
	"strconv"
	"time"

	"github.com/ProhtMeyhet/libgosimpleton/simpleton"
)

var random *rand.Rand

// open a file with FileHelper. if its a dir, return nil.
// it's your responsibility to close the file...
func Open(fileHelper *FileHelper, path string) (handler FileInterface, e error) {
	// FIXME TODO
/*	if path == abstract.STDIN_TOKEN {
		return NewFakeStdFile(fileHelper.Stdin(), fileHelper.Stdout())
	}*/

	handler, e = os.OpenFile(path, fileHelper.OpenFlags(), fileHelper.Permissions())
	if e != nil { fileHelper.RaiseError(path, e); goto out }
	if !fileHelper.DoNotTestForDirectory() {
		// ie := darn shadowing...
		fileInfo, ie := handler.Stat(); if ie != nil { e = ie; fileHelper.RaiseError(path, ie); goto out }
		if fileInfo.IsDir() { e = IsDirectoryError; fileHelper.RaiseError(path, e); goto out }
	}
	fileHelper.ApplyFileAdvice(handler)

out:
	return
}

// open N files. please keep limits like ulimit file.max in mind.
// see also parallel.OpenFiles() for a parallel version and parallel.OpenFilesIntoChannel()
// consider using iotool.ToggleFileAdviceWillNeed(). for error handling, use FileHelper.SetE().
// it's your responsibility to close the files...
func OpenFiles(fileHelper *FileHelper, files ...string) <-chan FileInterface {
	return OpenFilesFromChannel(fileHelper, simpleton.StringListToChannel(files...))
}

// open N files from channel. please keep limits like ulimit file.max in mind.
// see also parallel.OpenFiles() for a parallel version and parallel.OpenFilesIntoChannel()
// consider using iotool.ToggleFileAdviceWillNeed(). for error handling, use FileHelper.SetE().
// it's your responsibility to close the files...
func OpenFilesFromChannel(fileHelper *FileHelper, fileList <-chan string) <-chan FileInterface {
	handlers := make(chan FileInterface, fileHelper.WorkerBuffers())
	go func() {
		for path := range fileList {
			// no need to call fileHelper.RaiseError, it's called in Open() already
			if handler, e := Open(fileHelper, path); e == nil {
				handlers <-handler
			}
		}; close(handlers)
	}()
	return handlers
}

// create a file. if you need it truncated, use FileHelper.ToggleTruncate().
func Create(fileHelper *FileHelper, path string) (handler FileInterface, e error) {
	if !fileHelper.HasCreate() {
		fileHelper.ToggleCreate()
	}

	return Open(fileHelper, path)
}

// create a temporary file. only makes sure the file is unique. file will not be removed.
// prefix should be your program name.
func Temporary(fileHelper *FileHelper, prefix string) (handler FileInterface, e error) {
	if !fileHelper.HasExclusive() {
		fileHelper.ToggleExclusive()
	}

again:
	handler, e = Create(fileHelper, TemporaryName(prefix))
	if e != nil && os.IsExist(e) { goto again }

	// pass through all other errors, there isn't anything that can be done here
	return
}

// return a filename with full path in os.TempDir(). prefix should be your program name.
func TemporaryName(prefix string) string {
	// if not testing, seed with current time.
	if !DEBUG {
		if random == nil {
			// gotta seed manually these days...
			random = rand.New(rand.NewSource(time.Now().UnixNano()))
		}
	}
	return temporaryName(prefix)
}

// for testing purposes this function was split
func temporaryName(prefix string) string {
	directory := os.TempDir()
	name := prefix + PREFIX_SEPARATOR + strconv.Itoa(int(uint(random.Int63())))
	// FIXME: why the bloody fuck is os.PathSeparator a rune ?!?
	return directory + string(os.PathSeparator) + name
}

// close a bunch of files from a list.
func Close(fileList ...FileInterface) {
	for _, file := range fileList {
		file.Close()
	}
}

// give back a close chan to push FileInterfaces to; when done, close the channel.
func CloseChannel(fileHelper *FileHelper) chan<- FileInterface {
	closing := make(chan FileInterface, 16)
	CloseFilesFromChannel(fileHelper, closing)
	return closing
}

// close a bunch of files via a channel
func CloseFilesFromChannel(fileHelper *FileHelper, fileList chan FileInterface) {
	go func() {
		for handler := range fileList {
			if handler != nil {
				e := handler.Close(); if e != nil {
					fileHelper.RaiseError(handler.Name(), e)
				}
			}
		}
	}()
}

/* convinience functions */
// TODO add more

func Remove(handler FileInterface) error {
	return os.Remove(handler.Name())
}

// use FileHelper.ToggleTruncate(), otherwise os.Truncate().
// func Truncate(handler FileInterface, size int64) error {}
<commit_msg>minor fix<commit_after>package iotool

import(
	"math/rand"
	"os"
	"strconv"
	"time"

	"github.com/ProhtMeyhet/libgosimpleton/simpleton"
)

var random *rand.Rand

// open a file with FileHelper. if its a dir, return nil.
// it's your responsibility to close the file...
func Open(fileHelper *FileHelper, path string) (handler FileInterface, e error) {
	// FIXME TODO
/*	if path == abstract.STDIN_TOKEN {
		return NewFakeStdFile(fileHelper.Stdin(), fileHelper.Stdout())
	}*/

	handler, e = os.OpenFile(path, fileHelper.OpenFlags(), fileHelper.Permissions())
	if e != nil { fileHelper.RaiseError(path, e); goto out }
	if !fileHelper.DoNotTestForDirectory() {
		// ie := darn shadowing...
		fileInfo, ie := handler.Stat(); if ie != nil { e = ie; fileHelper.RaiseError(path, ie); goto out }
		if fileInfo.IsDir() { e = IsDirectoryError; fileHelper.RaiseError(path, e); goto out }
	}
	fileHelper.ApplyFileAdvice(handler)

out:
	return
}

// open N files. please keep limits like ulimit file.max in mind.
// see also parallel.OpenFiles() for a parallel version and parallel.OpenFilesIntoChannel()
// consider using iotool.ToggleFileAdviceWillNeed(). for error handling, use FileHelper.SetE().
// it's your responsibility to close the files...
func OpenFiles(fileHelper *FileHelper, files ...string) <-chan FileInterface {
	return OpenFilesFromChannel(fileHelper, simpleton.StringListToChannel(files...))
}

// open N files from channel. please keep limits like ulimit file.max in mind.
// see also parallel.OpenFiles() for a parallel version and parallel.OpenFilesIntoChannel()
// consider using iotool.ToggleFileAdviceWillNeed(). for error handling, use FileHelper.SetE().
// it's your responsibility to close the files...
func OpenFilesFromChannel(fileHelper *FileHelper, fileList <-chan string) <-chan FileInterface {
	handlers := make(chan FileInterface, fileHelper.WorkerBuffers())
	go func() {
		for path := range fileList {
			// no need to call fileHelper.RaiseError, it's called in Open() already
			if handler, e := Open(fileHelper, path); e == nil {
				handlers <-handler
			}
		}; close(handlers)
	}()
	return handlers
}

// create a file. if you need it truncated, use FileHelper.ToggleTruncate().
func Create(fileHelper *FileHelper, path string) (handler FileInterface, e error) {
	if !fileHelper.HasCreate() {
		fileHelper.ToggleCreate()
	}

	return Open(fileHelper, path)
}

// create a temporary file. only makes sure the file is unique. file will not be removed.
// prefix should be your program name.
func Temporary(fileHelper *FileHelper, prefix string) (handler FileInterface, e error) {
	if !fileHelper.HasExclusive() {
		fileHelper.ToggleExclusive()
	}

again:
	handler, e = Create(fileHelper, TemporaryName(prefix))
	if e != nil && os.IsExist(e) { goto again }

	// pass through all other errors, there isn't anything that can be done here
	return
}

// return a filename with full path in os.TempDir(). prefix should be your program name.
func TemporaryName(prefix string) string {
	if random == nil {
		// gotta seed manually these days...
		random = rand.New(rand.NewSource(time.Now().UnixNano()))
	}

	return temporaryName(prefix)
}

// for testing purposes this function was split
func temporaryName(prefix string) string {
	directory := os.TempDir()
	name := prefix + PREFIX_SEPARATOR + strconv.Itoa(int(uint(random.Int63())))
	// FIXME: why the bloody fuck is os.PathSeparator a rune ?!?
	return directory + string(os.PathSeparator) + name
}

// close a bunch of files from a list.
func Close(fileList ...FileInterface) {
	for _, file := range fileList {
		file.Close()
	}
}

// give back a close chan to push FileInterfaces to; when done, close the channel.
func CloseChannel(fileHelper *FileHelper) chan<- FileInterface {
	closing := make(chan FileInterface, 16)
	CloseFilesFromChannel(fileHelper, closing)
	return closing
}

// close a bunch of files via a channel
func CloseFilesFromChannel(fileHelper *FileHelper, fileList chan FileInterface) {
	go func() {
		for handler := range fileList {
			if handler != nil {
				e := handler.Close(); if e != nil {
					fileHelper.RaiseError(handler.Name(), e)
				}
			}
		}
	}()
}

/* convinience functions */
// TODO add more

func Remove(handler FileInterface) error {
	return os.Remove(handler.Name())
}

// use FileHelper.ToggleTruncate(), otherwise os.Truncate().
// func Truncate(handler FileInterface, size int64) error {}
<|endoftext|>


<commit_before>/*
package main

import (
	"container/heap"
	"encoding/json"
	"fmt"
	"log"
	"time"

	"github.com/boltdb/bolt"
	"github.com/gojp/goreportcard/check"
	"github.com/gojp/goreportcard/handlers"

	"gopkg.in/mgo.v2"
)

const (
	dbPath     string = "goreportcard.db"
	repoBucket string = "repos"
	metaBucket string = "meta"

	mongoURL        = "mongodb://127.0.0.1:27017"
	mongoDatabase   = "goreportcard"
	mongoCollection = "reports"
)

type Grade string

type score struct {
	Name          string              `json:"name"`
	Description   string              `json:"description"`
	FileSummaries []check.FileSummary `json:"file_summaries"`
	Weight        float64             `json:"weight"`
	Percentage    float64             `json:"percentage"`
}

type checksResp struct {
	Checks      []score   `json:"checks"`
	Average     float64   `json:"average"`
	Grade       Grade     `json:"grade"`
	Files       int       `json:"files"`
	Issues      int       `json:"issues"`
	Repo        string    `json:"repo"`
	LastRefresh time.Time `json:"last_refresh"`
}

// initDB opens the bolt database file (or creates it if it does not exist), and creates
// a bucket for saving the repos, also only if it does not exist.
func initDB() error {
	db, err := bolt.Open(handlers.DBPath, 0600, &bolt.Options{Timeout: 1 * time.Second})
	if err != nil {
		return err
	}
	defer db.Close()

	err = db.Update(func(tx *bolt.Tx) error {
		_, err := tx.CreateBucketIfNotExists([]byte(repoBucket))
		if err != nil {
			return err
		}
		_, err = tx.CreateBucketIfNotExists([]byte(metaBucket))
		return err
	})
	return err
}

func main() {
	// initialize bolt database
	if err := initDB(); err != nil {
		log.Fatal("ERROR: could not open bolt db: ", err)
	}

	session, err := mgo.Dial(mongoURL)
	if err != nil {
		log.Fatal("ERROR: could not get collection:", err)
	}
	defer session.Close()
	coll := session.DB(mongoDatabase).C(mongoCollection)

	db, err := bolt.Open(dbPath, 0755, &bolt.Options{Timeout: 1 * time.Second})
	if err != nil {
		log.Println("Failed to open bolt database: ", err)
		return
	}
	defer db.Close()

	var repos []checksResp
	coll.Find(nil).All(&repos)

	for _, repo := range repos {
		fmt.Printf("inserting %q into bolt...\n", repo.Repo)
		err = db.Update(func(tx *bolt.Tx) error {
			bkt := tx.Bucket([]byte(repoBucket))
			if bkt == nil {
				return fmt.Errorf("repo bucket not found")
			}
			b, err := json.Marshal(repo)
			if err != nil {
				return err
			}

			mb := tx.Bucket([]byte(metaBucket))
			if mb == nil {
				return fmt.Errorf("repo bucket not found")
			}
			updateHighScores(mb, repo, repo.Repo)

			return bkt.Put([]byte(repo.Repo), b)
		})
		if err != nil {
			log.Println("Bolt writing error:", err)
		}
	}

	err = db.Update(func(tx *bolt.Tx) error {
		mb := tx.Bucket([]byte(metaBucket))
		if mb == nil {
			return fmt.Errorf("repo bucket not found")
		}
		totalInt := len(repos)
		total, err := json.Marshal(totalInt)
		if err != nil {
			return fmt.Errorf("could not marshal total repos count: %v", err)
		}
		return mb.Put([]byte("total_repos"), total)
	})
	if err != nil {
		log.Fatal(err)
	}
}

func updateHighScores(mb *bolt.Bucket, resp checksResp, repo string) error {
	// check if we need to update the high score list
	if resp.Files < 100 {
		// only repos with >= 100 files are considered for the high score list
		return nil
	}

	// start updating high score list
	scoreBytes := mb.Get([]byte("scores"))
	if scoreBytes == nil {
		scoreBytes, _ = json.Marshal([]scoreHeap{})
	}
	scores := &scoreHeap{}
	json.Unmarshal(scoreBytes, scores)

	heap.Init(scores)
	if len(*scores) > 0 && (*scores)[0].Score > resp.Average*100.0 && len(*scores) == 50 {
		// lowest score on list is higher than this repo's score, so no need to add, unless
		// we do not have 50 high scores yet
		return nil
	}
	// if this repo is already in the list, remove the original entry:
	for i := range *scores {
		if (*scores)[i].Repo == repo {
			heap.Remove(scores, i)
			break
		}
	}
	// now we can safely push it onto the heap
	heap.Push(scores, scoreItem{
		Repo:  repo,
		Score: resp.Average * 100.0,
		Files: resp.Files,
	})
	if len(*scores) > 50 {
		// trim heap if it's grown to over 50
		*scores = (*scores)[1:51]
	}
	scoreBytes, err := json.Marshal(&scores)
	if err != nil {
		return err
	}
	err = mb.Put([]byte("scores"), scoreBytes)
	if err != nil {
		return err
	}

	return nil
}

type scoreItem struct {
	Repo  string  `json:"repo"`
	Score float64 `json:"score"`
	Files int     `json:"files"`
}

// An scoreHeap is a min-heap of ints.
type scoreHeap []scoreItem

func (h scoreHeap) Len() int           { return len(h) }
func (h scoreHeap) Less(i, j int) bool { return h[i].Score < h[j].Score }
func (h scoreHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }

func (h *scoreHeap) Push(x interface{}) {
	// Push and Pop use pointer receivers because they modify the slice's length,
	// not just its contents.
	*h = append(*h, x.(scoreItem))
}

func (h *scoreHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[0 : n-1]
	return x
}
*/
<commit_msg>fix comment<commit_after>package main

/*
import (
	"container/heap"
	"encoding/json"
	"fmt"
	"log"
	"time"

	"github.com/boltdb/bolt"
	"github.com/gojp/goreportcard/check"
	"github.com/gojp/goreportcard/handlers"

	"gopkg.in/mgo.v2"
)

const (
	dbPath     string = "goreportcard.db"
	repoBucket string = "repos"
	metaBucket string = "meta"

	mongoURL        = "mongodb://127.0.0.1:27017"
	mongoDatabase   = "goreportcard"
	mongoCollection = "reports"
)

type Grade string

type score struct {
	Name          string              `json:"name"`
	Description   string              `json:"description"`
	FileSummaries []check.FileSummary `json:"file_summaries"`
	Weight        float64             `json:"weight"`
	Percentage    float64             `json:"percentage"`
}

type checksResp struct {
	Checks      []score   `json:"checks"`
	Average     float64   `json:"average"`
	Grade       Grade     `json:"grade"`
	Files       int       `json:"files"`
	Issues      int       `json:"issues"`
	Repo        string    `json:"repo"`
	LastRefresh time.Time `json:"last_refresh"`
}

// initDB opens the bolt database file (or creates it if it does not exist), and creates
// a bucket for saving the repos, also only if it does not exist.
func initDB() error {
	db, err := bolt.Open(handlers.DBPath, 0600, &bolt.Options{Timeout: 1 * time.Second})
	if err != nil {
		return err
	}
	defer db.Close()

	err = db.Update(func(tx *bolt.Tx) error {
		_, err := tx.CreateBucketIfNotExists([]byte(repoBucket))
		if err != nil {
			return err
		}
		_, err = tx.CreateBucketIfNotExists([]byte(metaBucket))
		return err
	})
	return err
}

func main() {
	// initialize bolt database
	if err := initDB(); err != nil {
		log.Fatal("ERROR: could not open bolt db: ", err)
	}

	session, err := mgo.Dial(mongoURL)
	if err != nil {
		log.Fatal("ERROR: could not get collection:", err)
	}
	defer session.Close()
	coll := session.DB(mongoDatabase).C(mongoCollection)

	db, err := bolt.Open(dbPath, 0755, &bolt.Options{Timeout: 1 * time.Second})
	if err != nil {
		log.Println("Failed to open bolt database: ", err)
		return
	}
	defer db.Close()

	var repos []checksResp
	coll.Find(nil).All(&repos)

	for _, repo := range repos {
		fmt.Printf("inserting %q into bolt...\n", repo.Repo)
		err = db.Update(func(tx *bolt.Tx) error {
			bkt := tx.Bucket([]byte(repoBucket))
			if bkt == nil {
				return fmt.Errorf("repo bucket not found")
			}
			b, err := json.Marshal(repo)
			if err != nil {
				return err
			}

			mb := tx.Bucket([]byte(metaBucket))
			if mb == nil {
				return fmt.Errorf("repo bucket not found")
			}
			updateHighScores(mb, repo, repo.Repo)

			return bkt.Put([]byte(repo.Repo), b)
		})
		if err != nil {
			log.Println("Bolt writing error:", err)
		}
	}

	err = db.Update(func(tx *bolt.Tx) error {
		mb := tx.Bucket([]byte(metaBucket))
		if mb == nil {
			return fmt.Errorf("repo bucket not found")
		}
		totalInt := len(repos)
		total, err := json.Marshal(totalInt)
		if err != nil {
			return fmt.Errorf("could not marshal total repos count: %v", err)
		}
		return mb.Put([]byte("total_repos"), total)
	})
	if err != nil {
		log.Fatal(err)
	}
}

func updateHighScores(mb *bolt.Bucket, resp checksResp, repo string) error {
	// check if we need to update the high score list
	if resp.Files < 100 {
		// only repos with >= 100 files are considered for the high score list
		return nil
	}

	// start updating high score list
	scoreBytes := mb.Get([]byte("scores"))
	if scoreBytes == nil {
		scoreBytes, _ = json.Marshal([]scoreHeap{})
	}
	scores := &scoreHeap{}
	json.Unmarshal(scoreBytes, scores)

	heap.Init(scores)
	if len(*scores) > 0 && (*scores)[0].Score > resp.Average*100.0 && len(*scores) == 50 {
		// lowest score on list is higher than this repo's score, so no need to add, unless
		// we do not have 50 high scores yet
		return nil
	}
	// if this repo is already in the list, remove the original entry:
	for i := range *scores {
		if (*scores)[i].Repo == repo {
			heap.Remove(scores, i)
			break
		}
	}
	// now we can safely push it onto the heap
	heap.Push(scores, scoreItem{
		Repo:  repo,
		Score: resp.Average * 100.0,
		Files: resp.Files,
	})
	if len(*scores) > 50 {
		// trim heap if it's grown to over 50
		*scores = (*scores)[1:51]
	}
	scoreBytes, err := json.Marshal(&scores)
	if err != nil {
		return err
	}
	err = mb.Put([]byte("scores"), scoreBytes)
	if err != nil {
		return err
	}

	return nil
}

type scoreItem struct {
	Repo  string  `json:"repo"`
	Score float64 `json:"score"`
	Files int     `json:"files"`
}

// An scoreHeap is a min-heap of ints.
type scoreHeap []scoreItem

func (h scoreHeap) Len() int           { return len(h) }
func (h scoreHeap) Less(i, j int) bool { return h[i].Score < h[j].Score }
func (h scoreHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }

func (h *scoreHeap) Push(x interface{}) {
	// Push and Pop use pointer receivers because they modify the slice's length,
	// not just its contents.
	*h = append(*h, x.(scoreItem))
}

func (h *scoreHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[0 : n-1]
	return x
}
*/
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package filters

import (
	"encoding/json"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"reflect"
	"sync"
	"testing"
	"time"

	apierrors "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/apimachinery/pkg/util/diff"
	"k8s.io/apimachinery/pkg/util/runtime"
)

type recorder struct {
	lock  sync.Mutex
	count int
}

func (r *recorder) Record() {
	r.lock.Lock()
	defer r.lock.Unlock()
	r.count++
}

func (r *recorder) Count() int {
	r.lock.Lock()
	defer r.lock.Unlock()
	return r.count
}

func TestTimeout(t *testing.T) {
	origReallyCrash := runtime.ReallyCrash
	runtime.ReallyCrash = false
	defer func() {
		runtime.ReallyCrash = origReallyCrash
	}()

	sendResponse := make(chan struct{}, 1)
	doPanic := make(chan struct{}, 1)
	writeErrors := make(chan error, 1)
	timeout := make(chan time.Time, 1)
	resp := "test response"
	timeoutErr := apierrors.NewServerTimeout(schema.GroupResource{Group: "foo", Resource: "bar"}, "get", 0)
	record := &recorder{}

	ts := httptest.NewServer(WithPanicRecovery(WithTimeout(http.HandlerFunc(
		func(w http.ResponseWriter, r *http.Request) {
			select {
			case <-sendResponse:
				_, err := w.Write([]byte(resp))
				writeErrors <- err
			case <-doPanic:
				panic("inner handler panics")
			}
		}),
		func(req *http.Request) (*http.Request, <-chan time.Time, func(), *apierrors.StatusError) {
			return req, timeout, record.Record, timeoutErr
		})))
	defer ts.Close()

	// No timeouts
	sendResponse <- struct{}{}
	res, err := http.Get(ts.URL)
	if err != nil {
		t.Fatal(err)
	}
	if res.StatusCode != http.StatusOK {
		t.Errorf("got res.StatusCode %d; expected %d", res.StatusCode, http.StatusOK)
	}
	body, _ := ioutil.ReadAll(res.Body)
	if string(body) != resp {
		t.Errorf("got body %q; expected %q", string(body), resp)
	}
	if err := <-writeErrors; err != nil {
		t.Errorf("got unexpected Write error on first request: %v", err)
	}
	if record.Count() != 0 {
		t.Errorf("invoked record method: %#v", record)
	}

	// Times out
	timeout <- time.Time{}
	res, err = http.Get(ts.URL)
	if err != nil {
		t.Fatal(err)
	}
	if res.StatusCode != http.StatusGatewayTimeout {
		t.Errorf("got res.StatusCode %d; expected %d", res.StatusCode, http.StatusServiceUnavailable)
	}
	body, _ = ioutil.ReadAll(res.Body)
	status := &metav1.Status{}
	if err := json.Unmarshal(body, status); err != nil {
		t.Fatal(err)
	}
	if !reflect.DeepEqual(status, &timeoutErr.ErrStatus) {
		t.Errorf("unexpected object: %s", diff.ObjectReflectDiff(&timeoutErr.ErrStatus, status))
	}
	if record.Count() != 1 {
		t.Errorf("did not invoke record method: %#v", record)
	}

	// Now try to send a response
	sendResponse <- struct{}{}
	if err := <-writeErrors; err != http.ErrHandlerTimeout {
		t.Errorf("got Write error of %v; expected %v", err, http.ErrHandlerTimeout)
	}

	// Panics
	doPanic <- struct{}{}
	res, err = http.Get(ts.URL)
	if err != nil {
		t.Fatal(err)
	}
	if res.StatusCode != http.StatusInternalServerError {
		t.Errorf("got res.StatusCode %d; expected %d due to panic", res.StatusCode, http.StatusInternalServerError)
	}
}
<commit_msg>apiserver: in timeout_test separate out handler<commit_after>/*
Copyright 2016 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package filters

import (
	"encoding/json"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"reflect"
	"sync"
	"testing"
	"time"

	apierrors "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/apimachinery/pkg/util/diff"
	"k8s.io/apimachinery/pkg/util/runtime"
)

type recorder struct {
	lock  sync.Mutex
	count int
}

func (r *recorder) Record() {
	r.lock.Lock()
	defer r.lock.Unlock()
	r.count++
}

func (r *recorder) Count() int {
	r.lock.Lock()
	defer r.lock.Unlock()
	return r.count
}

func newHandler(responseCh <-chan string, panicCh <-chan struct{}, writeErrCh chan<- error) http.HandlerFunc {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		select {
		case resp := <-responseCh:
			_, err := w.Write([]byte(resp))
			writeErrCh <- err
		case <-panicCh:
			panic("inner handler panics")
		}
	})
}

func TestTimeout(t *testing.T) {
	origReallyCrash := runtime.ReallyCrash
	runtime.ReallyCrash = false
	defer func() {
		runtime.ReallyCrash = origReallyCrash
	}()

	sendResponse := make(chan string, 1)
	doPanic := make(chan struct{}, 1)
	writeErrors := make(chan error, 1)
	timeout := make(chan time.Time, 1)
	resp := "test response"
	timeoutErr := apierrors.NewServerTimeout(schema.GroupResource{Group: "foo", Resource: "bar"}, "get", 0)
	record := &recorder{}

	handler := newHandler(sendResponse, doPanic, writeErrors)
	ts := httptest.NewServer(WithPanicRecovery(WithTimeout(handler,
		func(req *http.Request) (*http.Request, <-chan time.Time, func(), *apierrors.StatusError) {
			return req, timeout, record.Record, timeoutErr
		})))
	defer ts.Close()

	// No timeouts
	sendResponse <- resp
	res, err := http.Get(ts.URL)
	if err != nil {
		t.Fatal(err)
	}
	if res.StatusCode != http.StatusOK {
		t.Errorf("got res.StatusCode %d; expected %d", res.StatusCode, http.StatusOK)
	}
	body, _ := ioutil.ReadAll(res.Body)
	if string(body) != resp {
		t.Errorf("got body %q; expected %q", string(body), resp)
	}
	if err := <-writeErrors; err != nil {
		t.Errorf("got unexpected Write error on first request: %v", err)
	}
	if record.Count() != 0 {
		t.Errorf("invoked record method: %#v", record)
	}

	// Times out
	timeout <- time.Time{}
	res, err = http.Get(ts.URL)
	if err != nil {
		t.Fatal(err)
	}
	if res.StatusCode != http.StatusGatewayTimeout {
		t.Errorf("got res.StatusCode %d; expected %d", res.StatusCode, http.StatusServiceUnavailable)
	}
	body, _ = ioutil.ReadAll(res.Body)
	status := &metav1.Status{}
	if err := json.Unmarshal(body, status); err != nil {
		t.Fatal(err)
	}
	if !reflect.DeepEqual(status, &timeoutErr.ErrStatus) {
		t.Errorf("unexpected object: %s", diff.ObjectReflectDiff(&timeoutErr.ErrStatus, status))
	}
	if record.Count() != 1 {
		t.Errorf("did not invoke record method: %#v", record)
	}

	// Now try to send a response
	sendResponse <- resp
	if err := <-writeErrors; err != http.ErrHandlerTimeout {
		t.Errorf("got Write error of %v; expected %v", err, http.ErrHandlerTimeout)
	}

	// Panics
	doPanic <- struct{}{}
	res, err = http.Get(ts.URL)
	if err != nil {
		t.Fatal(err)
	}
	if res.StatusCode != http.StatusInternalServerError {
		t.Errorf("got res.StatusCode %d; expected %d due to panic", res.StatusCode, http.StatusInternalServerError)
	}
}
<|endoftext|>