<commit_before>package integration

import (
	"fmt"

	. "code.cloudfoundry.org/cli/integration/helpers"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
)

var _ = FDescribe("run-task command", func() {
	var (
		orgName   string
		spaceName string
		appName   string
	)

	BeforeEach(func() {
		orgName = PrefixedRandomName("ORG")
		spaceName = PrefixedRandomName("SPACE")
		appName = PrefixedRandomName("APP")

		setupCF(orgName, spaceName)
	})

	AfterEach(func() {
		setAPI()
		loginCF()
		Eventually(CF("delete-org", "-f", orgName), CFLongTimeout).Should(Exit(0))
	})

	It("should display the command level help", func() {
		session := CF("run-task", "-h")
		Eventually(session).Should(Exit(0))
		Expect(session.Out).To(Say(`NAME:
   run-task - Run a one-off task on an app

USAGE:
   cf run-task APP_NAME COMMAND

EXAMPLES:
   cf run-task my-app "bundle exec rake db:migrate"

ALIAS:
   rt

SEE ALSO:
   tasks, terminate-task`))
	})

	Context("when the environment is not setup correctly", func() {
		Context("when no API endpoint is set", func() {
			BeforeEach(func() {
				unsetAPI()
			})

			It("fails with no API endpoint set message", func() {
				session := CF("run-task", "app-name", "some command")
				Eventually(session).Should(Exit(1))
				Expect(session.Out).To(Say("FAILED"))
				Expect(session.Err).To(Say("No API endpoint set. Use 'cf login' or 'cf api' to target an endpoint."))
			})
		})

		Context("when not logged in", func() {
			BeforeEach(func() {
				logoutCF()
			})

			It("fails with not logged in message", func() {
				session := CF("run-task", "app-name", "some command")
				Eventually(session).Should(Exit(1))
				Expect(session.Out).To(Say("FAILED"))
				Expect(session.Err).To(Say("Not logged in. Use 'cf login' to log in."))
			})
		})

		Context("when there no org set", func() {
			BeforeEach(func() {
				logoutCF()
				loginCF()
			})

			It("fails with no targeted org error message", func() {
				session := CF("run-task", "app-name", "some command")
				Eventually(session).Should(Exit(1))
				Expect(session.Out).To(Say("FAILED"))
				Expect(session.Err).To(Say("No org targeted, use 'cf target -o ORG' to target an org."))
			})
		})

		Context("when there no space set", func() {
			BeforeEach(func() {
				// create a another space, because if the org has only one space it
				// will be automatically targetted
				createSpace(PrefixedRandomName("SPACE"))
				logoutCF()
				loginCF()
				targetOrg(orgName)
			})

			It("fails with no space targeted error message", func() {
				session := CF("run-task", "app-name", "some command")
				Eventually(session).Should(Exit(1))
				Expect(session.Out).To(Say("FAILED"))
				Expect(session.Err).To(Say("No space targeted, use 'cf target -s SPACE' to target a space"))
			})
		})
	})

	Context("when the environment is setup correctly", func() {
		Context("when the application exists", func() {
			BeforeEach(func() {
				WithSimpleApp(func(appDir string) {
					Eventually(CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack"), CFLongTimeout).Should(Exit(0))
				})
			})

			It("creates a new task", func() {
				session := CF("run-task", appName, "echo hi")
				Eventually(session).Should(Exit(0))
				userName, _ := getCredentials()
				Expect(session.Out).To(Say(fmt.Sprintf("Creating task for app %s in org %s / space %s as %s...", appName, orgName, spaceName, userName)))
				Expect(session.Out).To(Say(`OK

Task 1 has been submitted successfully for execution.`,
				))
			})
		})

		Context("when the application is not staged", func() {
			BeforeEach(func() {
				WithSimpleApp(func(appDir string) {
					Eventually(CF("push", appName, "--no-start", "-p", appDir, "-b", "staticfile_buildpack"), CFLongTimeout).Should(Exit(0))
				})
			})

			It("fails and outputs task must have a droplet message", func() {
				session := CF("run-task", appName, "echo hi")
				Eventually(session).Should(Exit(1))
				Expect(session.Out).To(Say("FAILED"))
				Expect(session.Err).To(Say(`Error running task: Task must have a droplet. Specify droplet or assign current droplet to app.`))
			})
		})

		Context("when the application is staged but stopped", func() {
			BeforeEach(func() {
				WithSimpleApp(func(appDir string) {
					Eventually(CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack"), CFLongTimeout).Should(Exit(0))
				})
				session := CF("stop", appName)
				Eventually(session).Should(Exit(0))
			})

			It("creates a new task", func() {
				session := CF("run-task", appName, "echo hi")
				Eventually(session).Should(Exit(0))
				userName, _ := getCredentials()
				Expect(session.Out).To(Say(fmt.Sprintf("Creating task for app %s in org %s / space %s as %s...", appName, orgName, spaceName, userName)))
				Expect(session.Out).To(Say(`OK

Task 1 has been submitted successfully for execution.`,
				))
			})
		})

		Context("when the application does not exist", func() {
			It("fails and outputs an app not found message", func() {
				session := CF("run-task", appName, "echo hi")
				Eventually(session).Should(Exit(1))
				Expect(session.Out).To(Say("FAILED"))
				Expect(session.Err).To(Say(fmt.Sprintf("App %s not found", appName)))
			})
		})
	})
})
<commit_msg>remove focus<commit_after>package integration

import (
	"fmt"

	. "code.cloudfoundry.org/cli/integration/helpers"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
)

var _ = Describe("run-task command", func() {
	var (
		orgName   string
		spaceName string
		appName   string
	)

	BeforeEach(func() {
		orgName = PrefixedRandomName("ORG")
		spaceName = PrefixedRandomName("SPACE")
		appName = PrefixedRandomName("APP")

		setupCF(orgName, spaceName)
	})

	AfterEach(func() {
		setAPI()
		loginCF()
		Eventually(CF("delete-org", "-f", orgName), CFLongTimeout).Should(Exit(0))
	})

	It("should display the command level help", func() {
		session := CF("run-task", "-h")
		Eventually(session).Should(Exit(0))
		Expect(session.Out).To(Say(`NAME:
   run-task - Run a one-off task on an app

USAGE:
   cf run-task APP_NAME COMMAND

EXAMPLES:
   cf run-task my-app "bundle exec rake db:migrate"

ALIAS:
   rt

SEE ALSO:
   tasks, terminate-task`))
	})

	Context("when the environment is not setup correctly", func() {
		Context("when no API endpoint is set", func() {
			BeforeEach(func() {
				unsetAPI()
			})

			It("fails with no API endpoint set message", func() {
				session := CF("run-task", "app-name", "some command")
				Eventually(session).Should(Exit(1))
				Expect(session.Out).To(Say("FAILED"))
				Expect(session.Err).To(Say("No API endpoint set. Use 'cf login' or 'cf api' to target an endpoint."))
			})
		})

		Context("when not logged in", func() {
			BeforeEach(func() {
				logoutCF()
			})

			It("fails with not logged in message", func() {
				session := CF("run-task", "app-name", "some command")
				Eventually(session).Should(Exit(1))
				Expect(session.Out).To(Say("FAILED"))
				Expect(session.Err).To(Say("Not logged in. Use 'cf login' to log in."))
			})
		})

		Context("when there no org set", func() {
			BeforeEach(func() {
				logoutCF()
				loginCF()
			})

			It("fails with no targeted org error message", func() {
				session := CF("run-task", "app-name", "some command")
				Eventually(session).Should(Exit(1))
				Expect(session.Out).To(Say("FAILED"))
				Expect(session.Err).To(Say("No org targeted, use 'cf target -o ORG' to target an org."))
			})
		})

		Context("when there no space set", func() {
			BeforeEach(func() {
				// create a another space, because if the org has only one space it
				// will be automatically targetted
				createSpace(PrefixedRandomName("SPACE"))
				logoutCF()
				loginCF()
				targetOrg(orgName)
			})

			It("fails with no space targeted error message", func() {
				session := CF("run-task", "app-name", "some command")
				Eventually(session).Should(Exit(1))
				Expect(session.Out).To(Say("FAILED"))
				Expect(session.Err).To(Say("No space targeted, use 'cf target -s SPACE' to target a space"))
			})
		})
	})

	Context("when the environment is setup correctly", func() {
		Context("when the application exists", func() {
			BeforeEach(func() {
				WithSimpleApp(func(appDir string) {
					Eventually(CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack"), CFLongTimeout).Should(Exit(0))
				})
			})

			It("creates a new task", func() {
				session := CF("run-task", appName, "echo hi")
				Eventually(session).Should(Exit(0))
				userName, _ := getCredentials()
				Expect(session.Out).To(Say(fmt.Sprintf("Creating task for app %s in org %s / space %s as %s...", appName, orgName, spaceName, userName)))
				Expect(session.Out).To(Say(`OK

Task 1 has been submitted successfully for execution.`,
				))
			})
		})

		Context("when the application is not staged", func() {
			BeforeEach(func() {
				WithSimpleApp(func(appDir string) {
					Eventually(CF("push", appName, "--no-start", "-p", appDir, "-b", "staticfile_buildpack"), CFLongTimeout).Should(Exit(0))
				})
			})

			It("fails and outputs task must have a droplet message", func() {
				session := CF("run-task", appName, "echo hi")
				Eventually(session).Should(Exit(1))
				Expect(session.Out).To(Say("FAILED"))
				Expect(session.Err).To(Say(`Error running task: Task must have a droplet. Specify droplet or assign current droplet to app.`))
			})
		})

		Context("when the application is staged but stopped", func() {
			BeforeEach(func() {
				WithSimpleApp(func(appDir string) {
					Eventually(CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack"), CFLongTimeout).Should(Exit(0))
				})
				session := CF("stop", appName)
				Eventually(session).Should(Exit(0))
			})

			It("creates a new task", func() {
				session := CF("run-task", appName, "echo hi")
				Eventually(session).Should(Exit(0))
				userName, _ := getCredentials()
				Expect(session.Out).To(Say(fmt.Sprintf("Creating task for app %s in org %s / space %s as %s...", appName, orgName, spaceName, userName)))
				Expect(session.Out).To(Say(`OK

Task 1 has been submitted successfully for execution.`,
				))
			})
		})

		Context("when the application does not exist", func() {
			It("fails and outputs an app not found message", func() {
				session := CF("run-task", appName, "echo hi")
				Eventually(session).Should(Exit(1))
				Expect(session.Out).To(Say("FAILED"))
				Expect(session.Err).To(Say(fmt.Sprintf("App %s not found", appName)))
			})
		})
	})
})
<|endoftext|>


<commit_before>// Copyright 2012 The Plotinum Authors. All rights reserved.
// Use of this source code is governed by an MIT-style license
// that can be found in the LICENSE file.

package vg

const (
	// ptInch is the number of points in an inch.
	ptInch = 72
)

// A Length is a unit-independent representation of length.
// Internally, the length is stored in postscript points.
type Length float64

// Points returns a length for the given number of points.
func Points(pt float64) Length {
	return Length(pt)
}

// Inches returns a length for the given numer of inches.
func Inches(in float64) Length {
	return Length(in * ptInch)
}

// Dots returns the length in dots for the given Canvas.
func (l Length) Dots(c Canvas) float64 {
	return float64(l) / ptInch * c.DPI()
}

// Points returns the length in postscript points.
func (l Length) Points() float64 {
	return float64(l)
}

// Inches returns the length in inches.
func (l Length) Inches() float64 {
	return float64(l) / ptInch
}
<commit_msg>Add metric units to vg.Length.<commit_after>// Copyright 2012 The Plotinum Authors. All rights reserved.
// Use of this source code is governed by an MIT-style license
// that can be found in the LICENSE file.

package vg

// TODO(eaburns): These should be more like time.Duration.  I.e., 5*vg.Inch, 6*vg.Centimeter, etc., instead of requiring a function for each.

const (
	// PtInch is the number of points in an inch.
	ptInch = 72

	// PtCentimeter is the number of points in a centimeter.
	ptCentimeter = 28.3464567

	// PtMillimeter is the number of ponints in a millimeter.
	ptMillimeter = ptCentimeter / 10
)

// A Length is a unit-independent representation of length.
// Internally, the length is stored in postscript points.
type Length float64

// Points returns a length for the given number of points.
func Points(pt float64) Length {
	return Length(pt)
}

// Inches returns a length for the given numer of inches.
func Inches(in float64) Length {
	return Length(in * ptInch)
}

// Centimeters returns a length for the given number of centimeters.
func Centimeters(cm float64) Length {
	return Length(cm * ptCentimeter)
}

// Millimeters returns a length for the given number of millimeters.
func Millimeters(mm float64) Length {
	return Length(mm * ptMillimeter)
}

// Dots returns the length in dots for the given Canvas.
func (l Length) Dots(c Canvas) float64 {
	return float64(l) / ptInch * c.DPI()
}

// Points returns the length in postscript points.
func (l Length) Points() float64 {
	return float64(l)
}

// Inches returns the length in inches.
func (l Length) Inches() float64 {
	return float64(l) / ptInch
}

// Centimeters returns the length in centimeters.
func (l Length) Centimeters() float64 {
	return float64(l) / ptCentimeter
}

// Millimeters returns the length in millimeters.
func (l Length) Millimeters() float64 {
	return float64(l) / ptMillimeter
}
<|endoftext|>


<commit_before>package gcsx

import (
	"context"
	"testing"
	"time"

	"github.com/googlecloudplatform/gcsfuse/internal/storage"
	"github.com/jacobsa/gcloud/gcs"
	"github.com/jacobsa/gcloud/gcs/gcsfake"
	. "github.com/jacobsa/ogletest"
	"github.com/jacobsa/timeutil"
)

func TestFlags(t *testing.T) { RunTests(t) }

const TestBucketName string = "gcsfuse-default-bucket"

////////////////////////////////////////////////////////////////////////
// Boilerplate
////////////////////////////////////////////////////////////////////////

type BucketManagerTest struct {
	bucket            gcs.Bucket
	storageHandle     *storage.Storageclient
	fakeStorageServer storage.FakeStorage
}

var _ SetUpInterface = &BucketManagerTest{}

func init() { RegisterTestSuite(&BucketManagerTest{}) }

func (t *BucketManagerTest) SetUp(_ *TestInfo) {
	var err error
	t.storageHandle = t.fakeStorageServer.CreateStorageHandle()
	t.bucket, err = t.storageHandle.BucketHandle(TestBucketName)

	AssertEq(nil, err)
	AssertNe(nil, t.bucket)
}

func (t *BucketManagerTest) TearDown() {
	t.fakeStorageServer.ShutDown()
}

func (t *BucketManagerTest) TestNewBucketManagerMethod() {
	storageClient := t.storageHandle
	bucketConfig := BucketConfig{
		BillingProject:                     "BillingProject",
		OnlyDir:                            "OnlyDir",
		EgressBandwidthLimitBytesPerSecond: 7,
		OpRateLimitHz:                      11,
		StatCacheCapacity:                  100,
		StatCacheTTL:                       20 * time.Second,
		EnableMonitoring:                   true,
		DebugGCS:                           true,
		AppendThreshold:                    2,
		TmpObjectPrefix:                    "TmpObjectPrefix",
		EnableStorageClientLibrary:         true,
	}

	bm := NewBucketManager(bucketConfig, nil, storageClient)

	ExpectNe(nil, bm)
}

func (t *BucketManagerTest) TestSetupGcsBucketWhenEnableStorageClientLibraryIsTrue() {
	var bm bucketManager
	bm.storageHandle = t.storageHandle
	bm.config.EnableStorageClientLibrary = true
	bm.config.DebugGCS = true

	bucket, err := bm.SetUpGcsBucket(context.Background(), TestBucketName)

	ExpectNe(nil, bucket)
	ExpectEq(nil, err)
}

func (t *BucketManagerTest) TestSetupGcsBucketWhenEnableStorageClientLibraryIsFalse() {
	var bm bucketManager
	bm.storageHandle = t.storageHandle
	bm.config.EnableStorageClientLibrary = false
	bm.config.BillingProject = "BillingProject"
	bm.conn = &Connection{
		wrapped: gcsfake.NewConn(timeutil.RealClock()),
	}

	bucket, err := bm.SetUpGcsBucket(context.Background(), "fake@bucket")

	ExpectNe(nil, bucket)
	ExpectEq(nil, err)
}

func (t *BucketManagerTest) TestSetUpBucketMethod() {
	var bm bucketManager
	bucketConfig := BucketConfig{
		BillingProject:                     "BillingProject",
		OnlyDir:                            "OnlyDir",
		EgressBandwidthLimitBytesPerSecond: 7,
		OpRateLimitHz:                      11,
		StatCacheCapacity:                  100,
		StatCacheTTL:                       20 * time.Second,
		EnableMonitoring:                   true,
		DebugGCS:                           true,
		AppendThreshold:                    2,
		TmpObjectPrefix:                    "TmpObjectPrefix",
		EnableStorageClientLibrary:         true,
	}
	ctx := context.Background()
	bm.storageHandle = t.storageHandle
	bm.config = bucketConfig
	bm.gcCtx = ctx
	bm.conn = &Connection{
		wrapped: gcsfake.NewConn(timeutil.RealClock()),
	}

	bucket, err := bm.SetUpBucket(context.Background(), TestBucketName)

	ExpectNe(nil, bucket.Syncer)
	ExpectEq(nil, err)
}
<commit_msg>creating fakeStorageServer<commit_after>package gcsx

import (
	"context"
	"testing"
	"time"

	"github.com/googlecloudplatform/gcsfuse/internal/storage"
	"github.com/jacobsa/gcloud/gcs"
	"github.com/jacobsa/gcloud/gcs/gcsfake"
	. "github.com/jacobsa/ogletest"
	"github.com/jacobsa/timeutil"
)

func TestFlags(t *testing.T) { RunTests(t) }

const TestBucketName string = "gcsfuse-default-bucket"

////////////////////////////////////////////////////////////////////////
// Boilerplate
////////////////////////////////////////////////////////////////////////

type BucketManagerTest struct {
	bucket            gcs.Bucket
	storageHandle     *storage.Storageclient
	fakeStorageServer storage.FakeStorage
}

var _ SetUpInterface = &BucketManagerTest{}
var _ TearDownInterface = &BucketManagerTest{}

func init() { RegisterTestSuite(&BucketManagerTest{}) }

func (t *BucketManagerTest) SetUp(_ *TestInfo) {
	var err error
	t.storageHandle = t.fakeStorageServer.CreateStorageHandle()
	t.bucket, err = t.storageHandle.BucketHandle(TestBucketName)

	AssertEq(nil, err)
	AssertNe(nil, t.bucket)
}

func (t *BucketManagerTest) TearDown() {
	t.fakeStorageServer.ShutDown()
}

func (t *BucketManagerTest) TestNewBucketManagerMethod() {
	storageClient := t.storageHandle
	bucketConfig := BucketConfig{
		BillingProject:                     "BillingProject",
		OnlyDir:                            "OnlyDir",
		EgressBandwidthLimitBytesPerSecond: 7,
		OpRateLimitHz:                      11,
		StatCacheCapacity:                  100,
		StatCacheTTL:                       20 * time.Second,
		EnableMonitoring:                   true,
		DebugGCS:                           true,
		AppendThreshold:                    2,
		TmpObjectPrefix:                    "TmpObjectPrefix",
		EnableStorageClientLibrary:         true,
	}

	bm := NewBucketManager(bucketConfig, nil, storageClient)

	ExpectNe(nil, bm)
}

func (t *BucketManagerTest) TestSetupGcsBucketWhenEnableStorageClientLibraryIsTrue() {
	var bm bucketManager
	bm.storageHandle = t.storageHandle
	bm.config.EnableStorageClientLibrary = true
	bm.config.DebugGCS = true

	bucket, err := bm.SetUpGcsBucket(context.Background(), TestBucketName)

	ExpectNe(nil, bucket)
	ExpectEq(nil, err)
}

func (t *BucketManagerTest) TestSetupGcsBucketWhenEnableStorageClientLibraryIsFalse() {
	var bm bucketManager
	bm.storageHandle = t.storageHandle
	bm.config.EnableStorageClientLibrary = false
	bm.config.BillingProject = "BillingProject"
	bm.conn = &Connection{
		wrapped: gcsfake.NewConn(timeutil.RealClock()),
	}

	bucket, err := bm.SetUpGcsBucket(context.Background(), "fake@bucket")

	ExpectNe(nil, bucket)
	ExpectEq(nil, err)
}

func (t *BucketManagerTest) TestSetUpBucketMethod() {
	var bm bucketManager
	bucketConfig := BucketConfig{
		BillingProject:                     "BillingProject",
		OnlyDir:                            "OnlyDir",
		EgressBandwidthLimitBytesPerSecond: 7,
		OpRateLimitHz:                      11,
		StatCacheCapacity:                  100,
		StatCacheTTL:                       20 * time.Second,
		EnableMonitoring:                   true,
		DebugGCS:                           true,
		AppendThreshold:                    2,
		TmpObjectPrefix:                    "TmpObjectPrefix",
		EnableStorageClientLibrary:         true,
	}
	ctx := context.Background()
	bm.storageHandle = t.storageHandle
	bm.config = bucketConfig
	bm.gcCtx = ctx
	bm.conn = &Connection{
		wrapped: gcsfake.NewConn(timeutil.RealClock()),
	}

	bucket, err := bm.SetUpBucket(context.Background(), TestBucketName)

	ExpectNe(nil, bucket.Syncer)
	ExpectEq(nil, err)
}
<|endoftext|>


<commit_before>package gouv

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

func TestTTY(t *testing.T) {
	doTest(t, testTTY, 3)
}

func testTTY(t *testing.T, loop *UvLoop) {
	go func() {
		tty, err := UvTTYInit(loop, 1, 1, nil) // stdout with readable
		if err != nil {
			t.Fatal(err)
		}

		// if r := tty.SetMode(UV_TTY_MODE_NORMAL); r != 0 {
		// 	t.Fatal(ParseUvErr(r))
		// }

		sampleTTY(tty)

		fmt.Println(tty.GetWinsize())

		time.Sleep(2 * time.Second)

		// tty.ResetMode()

		// tty.Freemem()
	}()
}
<commit_msg>Try to fix incompatible of tty console in travis run<commit_after>package gouv

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

func TestTTY(t *testing.T) {
	doTest(t, testTTY, 3)
}

func testTTY(t *testing.T, loop *UvLoop) {
	go func() {
		defer func() {
			if e := recover(); e != nil {
				fmt.Println(e)
			}
		}()

		tty, err := UvTTYInit(loop, 1, 1, nil) // stdout with readable
		if err != nil {
			t.Fatal(err)
		}

		fmt.Println(tty.GetWinsize())

		if r := tty.SetMode(UV_TTY_MODE_NORMAL); r != 0 {
			t.Fatal(ParseUvErr(r))
		}

		sampleTTY(tty)

		time.Sleep(2 * time.Second)

		tty.ResetMode()

		tty.Freemem()
	}()
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"

	docker "github.com/fsouza/go-dockerclient"
)

type Volume struct {
	container *docker.APIContainers
	path      string
}

func (v *Volume) getBareFilename() string {
	str, err := getTrueName(v.container)
	if err != nil {
		log.Fatal(err.Error())
	}

	// remove leading backslash
	str = str[1:]

	// remove the "-volumes" suffix used to identify the container
	// as a data-only container in the first place
	if strings.HasSuffix(str, "-volumes") {
		str = str[0 : len(str)-7]
	}

	// Add the volume path with backslashes replaced by minuses.
	// Accidentally, this also give double minus
	// between the container name and the path.
	str += strings.Replace(v.path, "/", "-", -1)

	return str
}

func backupVolume(cli *docker.Client, directory string, v Volume) (string, error) {
	filename := v.getBareFilename() + ".tar"
	path := "/backup/" + filename
	hostpath := directory + filename

	user := strconv.Itoa(os.Geteuid())

	//cmd := "tar zcvf " + path + " " + v.path
	//log.Println(cmd)

	vols := make(map[string]struct{})
	vols["/backup/"] = struct{}{}

	binds := []string{
		directory + ":/backup/",
	}

	conf := &docker.Config{
		Cmd:         []string{"tar", "cvf", path, v.path},
		Image:       "busybox",
		User:        user,
		VolumesFrom: v.container.ID,
		Volumes:     vols,
	}
	hostconf := &docker.HostConfig{
		Binds:       binds,
		VolumesFrom: []string{v.container.ID},
	}
	opts := docker.CreateContainerOptions{
		Config:     conf,
		HostConfig: hostconf,
	}

	cont, err := cli.CreateContainer(opts)
	if err != nil {
		return "", err
	}

	//defer cli.RemoveContainer(docker.RemoveContainerOptions{ID: cont.ID, Force: true})

	err = cli.StartContainer(cont.ID, hostconf)
	if err != nil {
		return "", err
	}

	retcode, err := cli.WaitContainer(cont.ID)
	if err != nil {
		os.Remove(hostpath)
		return "", err
	}

	if retcode != 0 {
		os.Remove(hostpath)
		str := fmt.Sprintf("Failed to create volume backup - tar return code is %d", retcode)
		return "", errors.New(str)
	}

	fileinfo, err := os.Stat(hostpath)
	if err != nil {
		return "", err
	}

	if false == fileinfo.Mode().IsRegular() {
		str := fmt.Sprintf("Failed to create volume backup - created file %s is not regular", hostpath)
		return "", errors.New(str)
	}

	return hostpath, nil
}

//func createVolumeFilename
<commit_msg>remove the container after backup<commit_after>package main

import (
	"errors"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"

	docker "github.com/fsouza/go-dockerclient"
)

type Volume struct {
	container *docker.APIContainers
	path      string
}

func (v *Volume) getBareFilename() string {
	str, err := getTrueName(v.container)
	if err != nil {
		log.Fatal(err.Error())
	}

	// remove leading backslash
	str = str[1:]

	// remove the "-volumes" suffix used to identify the container
	// as a data-only container in the first place
	if strings.HasSuffix(str, "-volumes") {
		str = str[0 : len(str)-7]
	}

	// Add the volume path with backslashes replaced by minuses.
	// Accidentally, this also give double minus
	// between the container name and the path.
	str += strings.Replace(v.path, "/", "-", -1)

	return str
}

func backupVolume(cli *docker.Client, directory string, v Volume) (string, error) {
	filename := v.getBareFilename() + ".tar"
	path := "/backup/" + filename
	hostpath := directory + filename

	user := strconv.Itoa(os.Geteuid())

	//cmd := "tar zcvf " + path + " " + v.path
	//log.Println(cmd)

	vols := make(map[string]struct{})
	vols["/backup/"] = struct{}{}

	binds := []string{
		directory + ":/backup/",
	}

	conf := &docker.Config{
		Cmd:         []string{"tar", "cvf", path, v.path},
		Image:       "busybox",
		User:        user,
		VolumesFrom: v.container.ID,
		Volumes:     vols,
	}
	hostconf := &docker.HostConfig{
		Binds:       binds,
		VolumesFrom: []string{v.container.ID},
	}
	opts := docker.CreateContainerOptions{
		Config:     conf,
		HostConfig: hostconf,
	}

	cont, err := cli.CreateContainer(opts)
	if err != nil {
		return "", err
	}

	defer cli.RemoveContainer(docker.RemoveContainerOptions{ID: cont.ID, Force: true})

	err = cli.StartContainer(cont.ID, hostconf)
	if err != nil {
		return "", err
	}

	retcode, err := cli.WaitContainer(cont.ID)
	if err != nil {
		os.Remove(hostpath)
		return "", err
	}

	if retcode != 0 {
		os.Remove(hostpath)
		str := fmt.Sprintf("Failed to create volume backup - tar return code is %d", retcode)
		return "", errors.New(str)
	}

	fileinfo, err := os.Stat(hostpath)
	if err != nil {
		return "", err
	}

	if false == fileinfo.Mode().IsRegular() {
		str := fmt.Sprintf("Failed to create volume backup - created file %s is not regular", hostpath)
		return "", errors.New(str)
	}

	return hostpath, nil
}

//func createVolumeFilename
<|endoftext|>


<commit_before>package config

import (
	log "github.com/Sirupsen/logrus"

	"regexp"
	"strconv"
	"strings"
)

func getOrSetVal(args string, data map[interface{}]interface{}, value interface{}) interface{} {
	parts := strings.Split(args, ".")

	for i, part := range parts {
		val, ok := data[part]
		last := i+1 == len(parts)

		// Reached end, set the value
		if last && value != nil {
			if s, ok := value.(string); ok {
				value = DummyMarshall(s)
			}

			data[part] = value
			return value
		}

		// Missing intermediate key, create key
		if !last && value != nil && !ok {
			newData := map[interface{}]interface{}{}
			data[part] = newData
			data = newData
			continue
		}

		if !ok {
			break
		}

		if last {
			return val
		}

		newData, ok := val.(map[interface{}]interface{})
		if !ok {
			break
		}

		data = newData
	}

	return ""
}

func DummyMarshall(value string) interface{} {
	if strings.HasPrefix(value, "[") && strings.HasSuffix(value, "]") {
		return strings.Split(value[1:len(value)-1], ",")
	}

	if value == "true" {
		return true
	} else if value == "false" {
		return false
	} else if ok, _ := regexp.MatchString("^[0-9]+$", value); ok {
		i, err := strconv.Atoi(value)
		if err != nil {
			panic(err)
		}
		return i
	}

	return value
}

func parseCmdline(cmdLine string) map[interface{}]interface{} {
	result := make(map[interface{}]interface{})

outer:
	for _, part := range strings.Split(cmdLine, " ") {
		if !strings.HasPrefix(part, "rancher.") {
			continue
		}

		var value string
		kv := strings.SplitN(part, "=", 2)

		if len(kv) == 1 {
			value = "true"
		} else {
			value = kv[1]
		}

		current := result
		keys := strings.Split(kv[0], ".")[1:]
		for i, key := range keys {
			if i == len(keys)-1 {
				current[key] = DummyMarshall(value)
			} else {
				if obj, ok := current[key]; ok {
					if newCurrent, ok := obj.(map[interface{}]interface{}); ok {
						current = newCurrent
					} else {
						continue outer
					}
				} else {
					newCurrent := make(map[interface{}]interface{})
					current[key] = newCurrent
					current = newCurrent
				}
			}
		}
	}

	log.Debugf("Input obj %v", result)
	return result
}
<commit_msg>Trim whitespace for lists from rancherctl config set<commit_after>package config

import (
	log "github.com/Sirupsen/logrus"

	"regexp"
	"strconv"
	"strings"
)

func getOrSetVal(args string, data map[interface{}]interface{}, value interface{}) interface{} {
	parts := strings.Split(args, ".")

	for i, part := range parts {
		val, ok := data[part]
		last := i+1 == len(parts)

		// Reached end, set the value
		if last && value != nil {
			if s, ok := value.(string); ok {
				value = DummyMarshall(s)
			}

			data[part] = value
			return value
		}

		// Missing intermediate key, create key
		if !last && value != nil && !ok {
			newData := map[interface{}]interface{}{}
			data[part] = newData
			data = newData
			continue
		}

		if !ok {
			break
		}

		if last {
			return val
		}

		newData, ok := val.(map[interface{}]interface{})
		if !ok {
			break
		}

		data = newData
	}

	return ""
}

func DummyMarshall(value string) interface{} {
	if strings.HasPrefix(value, "[") && strings.HasSuffix(value, "]") {
		result := []string{}
		for _, i := range strings.Split(value[1:len(value)-1], ",") {
			result = append(result, strings.TrimSpace(i))
		}
		return result
	}

	if value == "true" {
		return true
	} else if value == "false" {
		return false
	} else if ok, _ := regexp.MatchString("^[0-9]+$", value); ok {
		i, err := strconv.Atoi(value)
		if err != nil {
			panic(err)
		}
		return i
	}

	return value
}

func parseCmdline(cmdLine string) map[interface{}]interface{} {
	result := make(map[interface{}]interface{})

outer:
	for _, part := range strings.Split(cmdLine, " ") {
		if !strings.HasPrefix(part, "rancher.") {
			continue
		}

		var value string
		kv := strings.SplitN(part, "=", 2)

		if len(kv) == 1 {
			value = "true"
		} else {
			value = kv[1]
		}

		current := result
		keys := strings.Split(kv[0], ".")[1:]
		for i, key := range keys {
			if i == len(keys)-1 {
				current[key] = DummyMarshall(value)
			} else {
				if obj, ok := current[key]; ok {
					if newCurrent, ok := obj.(map[interface{}]interface{}); ok {
						current = newCurrent
					} else {
						continue outer
					}
				} else {
					newCurrent := make(map[interface{}]interface{})
					current[key] = newCurrent
					current = newCurrent
				}
			}
		}
	}

	log.Debugf("Input obj %v", result)
	return result
}
<|endoftext|>


<commit_before>package http

import (
	"fmt"
	"github.com/pierrre/imageserver"
	"net/http"
	"regexp"
	"time"
)

var inmHeaderRegexp, _ = regexp.Compile("^\"(.+)\"$")

var expiresHeaderLocation, _ = time.LoadLocation("GMT")

type Server struct {
	HttpServer  *http.Server
	Parser      Parser
	ImageServer *imageserver.Server

	ExpiresDuration time.Duration
}

func (server *Server) Serve() {
	serveMux := http.NewServeMux()
	serveMux.HandleFunc("/", server.handleHttpRequest)
	server.HttpServer.Handler = serveMux
	server.HttpServer.ListenAndServe()
}

func (server *Server) handleHttpRequest(writer http.ResponseWriter, request *http.Request) {
	if request.Method != "GET" {
		server.sendError(writer, fmt.Errorf("Invalid request method"))
		return
	}

	parameters, err := server.Parser.Parse(request)
	if err != nil {
		server.sendError(writer, err)
		return
	}

	if server.checkNotModified(writer, request, parameters) {
		return
	}

	image, err := server.ImageServer.Get(parameters)

	if err != nil {
		server.sendError(writer, err)
		return
	}

	server.sendImage(writer, image, parameters)
}

func (server *Server) checkNotModified(writer http.ResponseWriter, request *http.Request, parameters imageserver.Parameters) bool {
	inmHeader := request.Header.Get("If-None-Match")
	if len(inmHeader) > 0 {
		matches := inmHeaderRegexp.FindStringSubmatch(inmHeader)
		if matches != nil && len(matches) == 2 {
			inm := matches[1]
			if inm == parameters.Hash() {
				writer.WriteHeader(304)
				return true
			}
		}
	}
	return false
}

func (server *Server) sendImage(writer http.ResponseWriter, image *imageserver.Image, parameters imageserver.Parameters) {
	if len(image.Type) > 0 {
		writer.Header().Set("Content-Type", "image/"+image.Type)
	}

	writer.Header().Set("Cache-Control", "public")

	if server.ExpiresDuration != 0 {
		t := time.Now()
		t = t.Add(server.ExpiresDuration)
		t = t.In(expiresHeaderLocation)
		writer.Header().Set("Expires", t.Format(time.RFC1123))
	}

	writer.Header().Set("ETag", fmt.Sprintf("\"%s\"", parameters.Hash()))

	writer.Write(image.Data)
}

func (server *Server) sendError(writer http.ResponseWriter, err error) {
	http.Error(writer, err.Error(), http.StatusBadRequest)
}
<commit_msg>Add http content length<commit_after>package http

import (
	"fmt"
	"github.com/pierrre/imageserver"
	"net/http"
	"regexp"
	"strconv"
	"time"
)

var inmHeaderRegexp, _ = regexp.Compile("^\"(.+)\"$")

var expiresHeaderLocation, _ = time.LoadLocation("GMT")

type Server struct {
	HttpServer  *http.Server
	Parser      Parser
	ImageServer *imageserver.Server

	ExpiresDuration time.Duration
}

func (server *Server) Serve() {
	serveMux := http.NewServeMux()
	serveMux.HandleFunc("/", server.handleHttpRequest)
	server.HttpServer.Handler = serveMux
	server.HttpServer.ListenAndServe()
}

func (server *Server) handleHttpRequest(writer http.ResponseWriter, request *http.Request) {
	if request.Method != "GET" {
		server.sendError(writer, fmt.Errorf("Invalid request method"))
		return
	}

	parameters, err := server.Parser.Parse(request)
	if err != nil {
		server.sendError(writer, err)
		return
	}

	if server.checkNotModified(writer, request, parameters) {
		return
	}

	image, err := server.ImageServer.Get(parameters)

	if err != nil {
		server.sendError(writer, err)
		return
	}

	server.sendImage(writer, image, parameters)
}

func (server *Server) checkNotModified(writer http.ResponseWriter, request *http.Request, parameters imageserver.Parameters) bool {
	inmHeader := request.Header.Get("If-None-Match")
	if len(inmHeader) > 0 {
		matches := inmHeaderRegexp.FindStringSubmatch(inmHeader)
		if matches != nil && len(matches) == 2 {
			inm := matches[1]
			if inm == parameters.Hash() {
				writer.WriteHeader(304)
				return true
			}
		}
	}
	return false
}

func (server *Server) sendImage(writer http.ResponseWriter, image *imageserver.Image, parameters imageserver.Parameters) {
	writer.Header().Set("Content-Length", strconv.Itoa(len(image.Data)))

	if len(image.Type) > 0 {
		writer.Header().Set("Content-Type", "image/"+image.Type)
	}

	writer.Header().Set("Cache-Control", "public")

	if server.ExpiresDuration != 0 {
		t := time.Now()
		t = t.Add(server.ExpiresDuration)
		t = t.In(expiresHeaderLocation)
		writer.Header().Set("Expires", t.Format(time.RFC1123))
	}

	writer.Header().Set("ETag", fmt.Sprintf("\"%s\"", parameters.Hash()))

	writer.Write(image.Data)
}

func (server *Server) sendError(writer http.ResponseWriter, err error) {
	http.Error(writer, err.Error(), http.StatusBadRequest)
}
<|endoftext|>


<commit_before>package s3gof3r

import (
	"net"
	"net/http"
	"time"
)

type deadlineConn struct {
	Timeout time.Duration
	net.Conn
}

func (c *deadlineConn) Read(b []byte) (n int, err error) {
	if err = c.Conn.SetDeadline(time.Now().Add(c.Timeout)); err != nil {
		return
	}
	return c.Conn.Read(b)
}

func (c *deadlineConn) Write(b []byte) (n int, err error) {
	if err = c.Conn.SetDeadline(time.Now().Add(c.Timeout)); err != nil {
		return
	}
	return c.Conn.Write(b)
}

func ClientWithTimeout(timeout time.Duration) *http.Client {
	transport := &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: func(netw, addr string) (net.Conn, error) {
			c, err := net.DialTimeout(netw, addr, timeout)
			if err != nil {
				return nil, err
			}
			if tc, ok := c.(*net.TCPConn); ok {
				tc.SetKeepAlive(true)
				tc.SetKeepAlivePeriod(timeout)
			}
			return &deadlineConn{timeout, c}, nil
		},
		ResponseHeaderTimeout: timeout,
		MaxIdleConnsPerHost:   20,
	}
	return &http.Client{Transport: transport}
}
<commit_msg>Document ClientWithTimeout.<commit_after>package s3gof3r

import (
	"net"
	"net/http"
	"time"
)

type deadlineConn struct {
	Timeout time.Duration
	net.Conn
}

func (c *deadlineConn) Read(b []byte) (n int, err error) {
	if err = c.Conn.SetDeadline(time.Now().Add(c.Timeout)); err != nil {
		return
	}
	return c.Conn.Read(b)
}

func (c *deadlineConn) Write(b []byte) (n int, err error) {
	if err = c.Conn.SetDeadline(time.Now().Add(c.Timeout)); err != nil {
		return
	}
	return c.Conn.Write(b)
}

// ClientWithTimeout is an http client optimized for high throughput
// to S3, It times out more agressively than the default
// http client in net/http as well as setting deadlines on the TCP connection
func ClientWithTimeout(timeout time.Duration) *http.Client {
	transport := &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: func(netw, addr string) (net.Conn, error) {
			c, err := net.DialTimeout(netw, addr, timeout)
			if err != nil {
				return nil, err
			}
			if tc, ok := c.(*net.TCPConn); ok {
				tc.SetKeepAlive(true)
				tc.SetKeepAlivePeriod(timeout)
			}
			return &deadlineConn{timeout, c}, nil
		},
		ResponseHeaderTimeout: timeout,
		MaxIdleConnsPerHost:   20,
	}
	return &http.Client{Transport: transport}
}
<|endoftext|>


<commit_before>package httpretry

import (
	"net"
	"net/http"
	"time"
)

// ClientWithTimeout is an http client optimized for high throughput.  It times
// out more agressively than the default http client in net/http as well as
// setting deadlines on the TCP connection.
//
// Taken from s3gof3r:
// https://github.com/rlmcpherson/s3gof3r/blob/1e759738ff170bd0381a848337db677dbdd6aa62/http_client.go
//
func ClientWithTimeout(timeout time.Duration) *http.Client {
	return ClientWithTimeouts(timeout, timeout, timeout)
}

// ClientWithTimeout is an http client optimized for high throughput.  It times
// out more agressively than the default http client in net/http as well as
// setting deadlines on the TCP connection.
//
// Taken from s3gof3r:
// https://github.com/rlmcpherson/s3gof3r/blob/1e759738ff170bd0381a848337db677dbdd6aa62/http_client.go
//
func ClientWithTimeouts(dialTimeout, kaTimeout, actTimeout time.Duration) *http.Client {
	transport := &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial:  DialWithTimeouts(dialTimeout, kaTimeout, actTimeout),
		ResponseHeaderTimeout: actTimeout,
		MaxIdleConnsPerHost:   10,
	}
	return &http.Client{Transport: transport}
}

// DialWithTimeout creates a Dial function that returns a connection with an
// inactivity timeout for the given duration.  This is designed for long running
// HTTP requests.
func DialWithTimeout(timeout time.Duration) func(netw, addr string) (net.Conn, error) {
	return DialWithTimeouts(timeout, timeout, timeout)
}

// DialWithTimeouts creates a Dial function that returns a connection with
// separate timeouts for dialing the connection, maintaining the keep-alive
// connection, and inactivity.  This is designed for long running HTTP requests.
func DialWithTimeouts(dialTimeout, kaTimeout, actTimeout time.Duration) func(netw, addr string) (net.Conn, error) {
	return func(netw, addr string) (net.Conn, error) {
		c, err := net.DialTimeout(netw, addr, dialTimeout)
		if err != nil {
			return nil, err
		}
		if tc, ok := c.(*net.TCPConn); ok {
			tc.SetKeepAlive(true)
			tc.SetKeepAlivePeriod(kaTimeout)
		}
		return &deadlineConn{actTimeout, c}, nil
	}
}

type deadlineConn struct {
	Timeout time.Duration
	net.Conn
}

func (c *deadlineConn) Read(b []byte) (int, error) {
	if err := c.Conn.SetDeadline(time.Now().Add(c.Timeout)); err != nil {
		return 0, err
	}
	return c.Conn.Read(b)
}

func (c *deadlineConn) Write(b []byte) (int, error) {
	if err := c.Conn.SetDeadline(time.Now().Add(c.Timeout)); err != nil {
		return 0, err
	}

	return c.Conn.Write(b)
}
<commit_msg>configure timeouts with properties, not positional args<commit_after>package httpretry

import (
	"net"
	"net/http"
	"time"
)

type dialer struct {
	Timeout    time.Duration
	KeepAlive  time.Duration
	Inactivity time.Duration
}

func (d *dialer) Dial(netw, addr string) (net.Conn, error) {
	c, err := net.DialTimeout(netw, addr, d.Timeout)
	if err != nil {
		return nil, err
	}
	if tc, ok := c.(*net.TCPConn); ok {
		tc.SetKeepAlive(true)
		tc.SetKeepAlivePeriod(d.KeepAlive)
	}
	return &deadlineConn{d.Inactivity, c}, nil
}

// ClientWithTimeout is an http client optimized for high throughput.  It times
// out more agressively than the default http client in net/http as well as
// setting deadlines on the TCP connection.
//
// Taken from s3gof3r:
// https://github.com/rlmcpherson/s3gof3r/blob/1e759738ff170bd0381a848337db677dbdd6aa62/http_client.go
//
func ClientWithTimeout(timeout time.Duration) *http.Client {
	dialer := NewDialer(timeout)
	transport := &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial:  dialer.Dial,
		ResponseHeaderTimeout: dialer.Inactivity,
		MaxIdleConnsPerHost:   10,
	}
	return &http.Client{Transport: transport}
}

// DialWithTimeout creates a Dial function that returns a connection with an
// inactivity timeout for the given duration.  This is designed for long running
// HTTP requests.
func DialWithTimeout(timeout time.Duration) func(netw, addr string) (net.Conn, error) {
	return NewDialer(timeout).Dial
}

// DialWithTimeouts creates a Dial function that returns a connection with
// separate timeouts for dialing the connection, maintaining the keep-alive
// connection, and inactivity.  This is designed for long running HTTP requests.
func NewDialer(timeout time.Duration) *dialer {
	return &dialer{Timeout: timeout, KeepAlive: timeout, Inactivity: timeout}
}

type deadlineConn struct {
	Timeout time.Duration
	net.Conn
}

func (c *deadlineConn) Read(b []byte) (int, error) {
	if err := c.Conn.SetDeadline(time.Now().Add(c.Timeout)); err != nil {
		return 0, err
	}
	return c.Conn.Read(b)
}

func (c *deadlineConn) Write(b []byte) (int, error) {
	if err := c.Conn.SetDeadline(time.Now().Add(c.Timeout)); err != nil {
		return 0, err
	}

	return c.Conn.Write(b)
}
<|endoftext|>


<commit_before>package sudoku

import (
	"fmt"
	"log"
	"math"
	"strings"
)

//The actual techniques are intialized in hs_techniques.go, an actually defined in hst_*.go files.
var Techniques []SolveTechnique

//Worst case scenario, how many times we'd call HumanSolve to get a difficulty.
const MAX_DIFFICULTY_ITERATIONS = 50

//We will use this as our max to return a normalized difficulty.
//TODO: set this more accurately so we rarely hit it (it's very important to get this right!)
//This is just set emperically.
const MAX_RAW_DIFFICULTY = 18000.0

//How close we have to get to the average to feel comfortable our difficulty is converging.
const DIFFICULTY_CONVERGENCE = 0.0005

type SolveDirections []*SolveStep

const (
	NAKED_SINGLE = iota
	HIDDEN_SINGLE_IN_ROW
	HIDDEN_SINGLE_IN_COL
	HIDDEN_SINGLE_IN_BLOCK
)

type SolveStep struct {
	TargetCells  CellList
	PointerCells CellList
	Nums         IntSlice
	Technique    SolveTechnique
}

func (self *SolveStep) IsUseful(grid *Grid) bool {
	//Returns true IFF calling Apply with this step and the given grid would result in some useful work. Does not modify the gri.d

	//All of this logic is substantially recreated in Apply.

	if self.Technique == nil {
		return false
	}

	//TODO: test this.
	if self.Technique.IsFill() {
		if len(self.TargetCells) == 0 || len(self.Nums) == 0 {
			return false
		}
		cell := self.TargetCells[0].InGrid(grid)
		return self.Nums[0] != cell.Number()
	} else {
		useful := false
		for _, cell := range self.TargetCells {
			gridCell := cell.InGrid(grid)
			for _, exclude := range self.Nums {
				//It's right to use Possible because it includes the logic of "it's not possible if there's a number in there already"
				//TODO: ensure the comment above is correct logically.
				if gridCell.Possible(exclude) {
					useful = true
				}
			}
		}
		return useful
	}
}

func (self *SolveStep) Apply(grid *Grid) {
	//All of this logic is substantially recreated in IsUseful.
	if self.Technique.IsFill() {
		if len(self.TargetCells) == 0 || len(self.Nums) == 0 {
			return
		}
		cell := self.TargetCells[0].InGrid(grid)
		cell.SetNumber(self.Nums[0])
	} else {
		for _, cell := range self.TargetCells {
			gridCell := cell.InGrid(grid)
			for _, exclude := range self.Nums {
				gridCell.setExcluded(exclude, true)
			}
		}
	}
}

func (self *SolveStep) Description() string {
	result := ""
	if self.Technique.IsFill() {
		result += fmt.Sprintf("We put %s in cell %s ", self.Nums.Description(), self.TargetCells.Description())
	} else {
		//TODO: pluralize based on length of lists.
		result += fmt.Sprintf("We remove the possibilities %s from cells %s ", self.Nums.Description(), self.TargetCells.Description())
	}
	result += "because " + self.Technique.Description(self) + "."
	return result
}

func (self SolveDirections) Description() []string {

	if len(self) == 0 {
		return []string{""}
	}

	descriptions := make([]string, len(self))

	for i, step := range self {
		intro := ""
		switch i {
		case 0:
			intro = "First, "
		case len(self) - 1:
			intro = "Finally, "
		default:
			//TODO: switch between "then" and "next" randomly.
			intro = "Next, "
		}
		descriptions[i] = intro + strings.ToLower(step.Description())

	}
	return descriptions
}

func (self SolveDirections) Difficulty() float64 {
	//How difficult the solve directions described are. The measure of difficulty we use is
	//just summing up weights we see; this captures:
	//* Number of steps
	//* Average difficulty of steps
	//* Number of hard steps
	//* (kind of) the hardest step: because the difficulties go up expontentionally.

	//TODO: what's a good max bound for difficulty? This should be normalized to 0<->1 based on that.

	accum := 0.0
	for _, step := range self {
		accum += step.Technique.Difficulty()
	}

	if accum > MAX_RAW_DIFFICULTY {
		log.Println("Accumulated difficulty exceeded max difficulty: ", accum)
		accum = MAX_RAW_DIFFICULTY
	}

	return accum / MAX_RAW_DIFFICULTY

}

func (self SolveDirections) Walkthrough(grid *Grid) string {

	//TODO: test this.

	clone := grid.Copy()
	defer clone.Done()

	DIVIDER := "\n\n--------------------------------------------\n\n"

	intro := fmt.Sprintf("This will take %d steps to solve.", len(self))

	intro += "\nWhen you start, your grid looks like this:\n"

	intro += clone.Diagram()

	intro += "\n"

	intro += DIVIDER

	descriptions := self.Description()

	results := make([]string, len(self))

	for i, description := range descriptions {

		result := description + "\n"
		result += "After doing that, your grid will look like: \n\n"

		self[i].Apply(clone)

		result += grid.Diagram()

		results[i] = result
	}

	return intro + strings.Join(results, DIVIDER) + DIVIDER + "Now the puzzle is solved."
}

func (self *Grid) HumanWalkthrough() string {
	steps := self.HumanSolution()
	return steps.Walkthrough(self)
}

func (self *Grid) HumanSolution() SolveDirections {
	clone := self.Copy()
	defer clone.Done()
	return clone.HumanSolve()
}

func (self *Grid) HumanSolve() SolveDirections {

	var results []*SolveStep
	numTechniques := len(Techniques)

	//Note: trying these all in parallel is much slower (~15x) than doing them in sequence.
	//The reason is that in sequence we bailed early as soon as we found one step; now we try them all.

	for !self.Solved() {
		//TODO: provide hints to the techniques of where to look based on the last filled cell

		possibilitiesChan := make(chan []*SolveStep)

		var possibilities []*SolveStep

		for _, technique := range Techniques {
			go func(theTechnique SolveTechnique) {
				possibilitiesChan <- theTechnique.Find(self)
			}(technique)
		}

		//Collect all of the results

		for i := 0; i < numTechniques; i++ {

			for _, possibility := range <-possibilitiesChan {
				if possibility.IsUseful(self) {
					possibilities = append(possibilities, possibility)
				} else {
					log.Println("Rejecting a not useful suggestion: ", possibility)
				}
			}
		}

		//Now pick one to apply.
		if len(possibilities) == 0 {
			//Hmm, didn't find any possivbilities. We failed. :-(
			break
		}

		//TODO: consider if we should stop picking techniques based on their weight here.
		//Now that Find returns a slice instead of a single, we're already much more likely to select an "easy" technique. ... Right?

		possibilitiesWeights := make([]float64, len(possibilities))
		for i, possibility := range possibilities {
			possibilitiesWeights[i] = possibility.Technique.Difficulty()
		}
		step := possibilities[randomIndexWithInvertedWeights(possibilitiesWeights)]

		results = append(results, step)
		step.Apply(self)

	}
	if !self.Solved() {
		//We couldn't solve the puzzle.
		return nil
	}
	return results
}

func (self *Grid) Difficulty() float64 {
	//This can be an extremely expensive method. Do not call repeatedly!
	//returns the difficulty of the grid, which is a number between 0.0 and 1.0.
	//This is a probabilistic measure; repeated calls may return different numbers, although generally we wait for the results to converge.

	//We solve the same puzzle N times, then ask each set of steps for their difficulty, and combine those to come up with the overall difficulty.

	accum := 0.0
	average := 0.0
	lastAverage := 0.0

	for i := 0; i < MAX_DIFFICULTY_ITERATIONS; i++ {
		grid := self.Copy()
		steps := grid.HumanSolve()
		difficulty := steps.Difficulty()

		accum += difficulty
		average = accum / (float64(i) + 1.0)

		if math.Abs(average-lastAverage) < DIFFICULTY_CONVERGENCE {
			//Okay, we've already converged. Just return early!
			return average
		}

		lastAverage = average
	}

	//We weren't converging... oh well!
	return average

}
<commit_msg>Removed a vestigal const block for each solve technique (or the early ones, anyway) that didn't actually do anything.<commit_after>package sudoku

import (
	"fmt"
	"log"
	"math"
	"strings"
)

//The actual techniques are intialized in hs_techniques.go, and actually defined in hst_*.go files.
var Techniques []SolveTechnique

//Worst case scenario, how many times we'd call HumanSolve to get a difficulty.
const MAX_DIFFICULTY_ITERATIONS = 50

//We will use this as our max to return a normalized difficulty.
//TODO: set this more accurately so we rarely hit it (it's very important to get this right!)
//This is just set emperically.
const MAX_RAW_DIFFICULTY = 18000.0

//How close we have to get to the average to feel comfortable our difficulty is converging.
const DIFFICULTY_CONVERGENCE = 0.0005

type SolveDirections []*SolveStep

type SolveStep struct {
	TargetCells  CellList
	PointerCells CellList
	Nums         IntSlice
	Technique    SolveTechnique
}

func (self *SolveStep) IsUseful(grid *Grid) bool {
	//Returns true IFF calling Apply with this step and the given grid would result in some useful work. Does not modify the gri.d

	//All of this logic is substantially recreated in Apply.

	if self.Technique == nil {
		return false
	}

	//TODO: test this.
	if self.Technique.IsFill() {
		if len(self.TargetCells) == 0 || len(self.Nums) == 0 {
			return false
		}
		cell := self.TargetCells[0].InGrid(grid)
		return self.Nums[0] != cell.Number()
	} else {
		useful := false
		for _, cell := range self.TargetCells {
			gridCell := cell.InGrid(grid)
			for _, exclude := range self.Nums {
				//It's right to use Possible because it includes the logic of "it's not possible if there's a number in there already"
				//TODO: ensure the comment above is correct logically.
				if gridCell.Possible(exclude) {
					useful = true
				}
			}
		}
		return useful
	}
}

func (self *SolveStep) Apply(grid *Grid) {
	//All of this logic is substantially recreated in IsUseful.
	if self.Technique.IsFill() {
		if len(self.TargetCells) == 0 || len(self.Nums) == 0 {
			return
		}
		cell := self.TargetCells[0].InGrid(grid)
		cell.SetNumber(self.Nums[0])
	} else {
		for _, cell := range self.TargetCells {
			gridCell := cell.InGrid(grid)
			for _, exclude := range self.Nums {
				gridCell.setExcluded(exclude, true)
			}
		}
	}
}

func (self *SolveStep) Description() string {
	result := ""
	if self.Technique.IsFill() {
		result += fmt.Sprintf("We put %s in cell %s ", self.Nums.Description(), self.TargetCells.Description())
	} else {
		//TODO: pluralize based on length of lists.
		result += fmt.Sprintf("We remove the possibilities %s from cells %s ", self.Nums.Description(), self.TargetCells.Description())
	}
	result += "because " + self.Technique.Description(self) + "."
	return result
}

func (self SolveDirections) Description() []string {

	if len(self) == 0 {
		return []string{""}
	}

	descriptions := make([]string, len(self))

	for i, step := range self {
		intro := ""
		switch i {
		case 0:
			intro = "First, "
		case len(self) - 1:
			intro = "Finally, "
		default:
			//TODO: switch between "then" and "next" randomly.
			intro = "Next, "
		}
		descriptions[i] = intro + strings.ToLower(step.Description())

	}
	return descriptions
}

func (self SolveDirections) Difficulty() float64 {
	//How difficult the solve directions described are. The measure of difficulty we use is
	//just summing up weights we see; this captures:
	//* Number of steps
	//* Average difficulty of steps
	//* Number of hard steps
	//* (kind of) the hardest step: because the difficulties go up expontentionally.

	//TODO: what's a good max bound for difficulty? This should be normalized to 0<->1 based on that.

	accum := 0.0
	for _, step := range self {
		accum += step.Technique.Difficulty()
	}

	if accum > MAX_RAW_DIFFICULTY {
		log.Println("Accumulated difficulty exceeded max difficulty: ", accum)
		accum = MAX_RAW_DIFFICULTY
	}

	return accum / MAX_RAW_DIFFICULTY

}

func (self SolveDirections) Walkthrough(grid *Grid) string {

	//TODO: test this.

	clone := grid.Copy()
	defer clone.Done()

	DIVIDER := "\n\n--------------------------------------------\n\n"

	intro := fmt.Sprintf("This will take %d steps to solve.", len(self))

	intro += "\nWhen you start, your grid looks like this:\n"

	intro += clone.Diagram()

	intro += "\n"

	intro += DIVIDER

	descriptions := self.Description()

	results := make([]string, len(self))

	for i, description := range descriptions {

		result := description + "\n"
		result += "After doing that, your grid will look like: \n\n"

		self[i].Apply(clone)

		result += grid.Diagram()

		results[i] = result
	}

	return intro + strings.Join(results, DIVIDER) + DIVIDER + "Now the puzzle is solved."
}

func (self *Grid) HumanWalkthrough() string {
	steps := self.HumanSolution()
	return steps.Walkthrough(self)
}

func (self *Grid) HumanSolution() SolveDirections {
	clone := self.Copy()
	defer clone.Done()
	return clone.HumanSolve()
}

func (self *Grid) HumanSolve() SolveDirections {

	var results []*SolveStep
	numTechniques := len(Techniques)

	//Note: trying these all in parallel is much slower (~15x) than doing them in sequence.
	//The reason is that in sequence we bailed early as soon as we found one step; now we try them all.

	for !self.Solved() {
		//TODO: provide hints to the techniques of where to look based on the last filled cell

		possibilitiesChan := make(chan []*SolveStep)

		var possibilities []*SolveStep

		for _, technique := range Techniques {
			go func(theTechnique SolveTechnique) {
				possibilitiesChan <- theTechnique.Find(self)
			}(technique)
		}

		//Collect all of the results

		for i := 0; i < numTechniques; i++ {

			for _, possibility := range <-possibilitiesChan {
				if possibility.IsUseful(self) {
					possibilities = append(possibilities, possibility)
				} else {
					log.Println("Rejecting a not useful suggestion: ", possibility)
				}
			}
		}

		//Now pick one to apply.
		if len(possibilities) == 0 {
			//Hmm, didn't find any possivbilities. We failed. :-(
			break
		}

		//TODO: consider if we should stop picking techniques based on their weight here.
		//Now that Find returns a slice instead of a single, we're already much more likely to select an "easy" technique. ... Right?

		possibilitiesWeights := make([]float64, len(possibilities))
		for i, possibility := range possibilities {
			possibilitiesWeights[i] = possibility.Technique.Difficulty()
		}
		step := possibilities[randomIndexWithInvertedWeights(possibilitiesWeights)]

		results = append(results, step)
		step.Apply(self)

	}
	if !self.Solved() {
		//We couldn't solve the puzzle.
		return nil
	}
	return results
}

func (self *Grid) Difficulty() float64 {
	//This can be an extremely expensive method. Do not call repeatedly!
	//returns the difficulty of the grid, which is a number between 0.0 and 1.0.
	//This is a probabilistic measure; repeated calls may return different numbers, although generally we wait for the results to converge.

	//We solve the same puzzle N times, then ask each set of steps for their difficulty, and combine those to come up with the overall difficulty.

	accum := 0.0
	average := 0.0
	lastAverage := 0.0

	for i := 0; i < MAX_DIFFICULTY_ITERATIONS; i++ {
		grid := self.Copy()
		steps := grid.HumanSolve()
		difficulty := steps.Difficulty()

		accum += difficulty
		average = accum / (float64(i) + 1.0)

		if math.Abs(average-lastAverage) < DIFFICULTY_CONVERGENCE {
			//Okay, we've already converged. Just return early!
			return average
		}

		lastAverage = average
	}

	//We weren't converging... oh well!
	return average

}
<|endoftext|>


<commit_before>package main

import (
	"github.com/disintegration/imaging"
	"github.com/minotar/minecraft"
	"image"
	"image/draw"
	"image/png"
	"io"
)

const (
	HeadX      = 8
	HeadY      = 8
	HeadWidth  = 8
	HeadHeight = 8

	HelmX      = 40
	HelmY      = 8
	HelmWidth  = 8
	HelmHeight = 8

	TorsoX      = 20
	TorsoY      = 20
	TorsoWidth  = 8
	TorsoHeight = 12

	RaX      = 44
	RaY      = 20
	RaWidth  = 4
	RaHeight = 12

	RlX      = 4
	RlY      = 20
	RlWidth  = 4
	RlHeight = 12

	LaX      = 36
	LaY      = 52
	LaWidth  = 4
	LaHeight = 12

	LlX      = 20
	LlY      = 52
	LlWidth  = 4
	LlHeight = 12

	// The height of the 'bust' relative to the width of the body (16)
	BustHeight = 16
)

type mcSkin struct {
	Processed image.Image
	minecraft.Skin
}

func (skin *mcSkin) GetHead() error {
	skin.Processed = cropHead(skin.Image)
	return nil
}

func (skin *mcSkin) GetHelm() error {
	skin.Processed = cropHelm(skin.Image)
	return nil
}

func (skin *mcSkin) GetBody() error {
	// Check if 1.8 skin (the max Y bound should be 64)
	render18Skin := true
	bounds := skin.Image.Bounds()
	if bounds.Max.Y != 64 {
		render18Skin = false
	}

	helmImg := cropHelm(skin.Image)
	torsoImg := imaging.Crop(skin.Image, image.Rect(TorsoX, TorsoY, TorsoX+TorsoWidth, TorsoY+TorsoHeight))
	raImg := imaging.Crop(skin.Image, image.Rect(RaX, RaY, RaX+RaWidth, RaY+RaHeight))
	rlImg := imaging.Crop(skin.Image, image.Rect(RlX, RlY, RlX+RlWidth, RlY+RlHeight))

	var laImg, llImg image.Image

	// If the skin is 1.8 then we will use the left arms and legs, otherwise flip the right ones and use them.
	if render18Skin {
		laImg = imaging.Crop(skin.Image, image.Rect(LaX, LaY, LaX+LaWidth, LaY+LaHeight))
		llImg = imaging.Crop(skin.Image, image.Rect(LlX, LlY, LlX+LlWidth, LlY+LlHeight))
	} else {
		laImg = imaging.FlipH(raImg)

		llImg = imaging.FlipH(rlImg)
	}

	// Create a blank canvas for us to draw our body on
	bodyImg := image.NewRGBA(image.Rect(0, 0, LaWidth+TorsoWidth+RaWidth, HeadHeight+TorsoHeight+LlHeight))
	// Helm
	draw.Draw(bodyImg, image.Rect(LaWidth, 0, LaWidth+HelmWidth, HelmHeight), helmImg, image.Pt(0, 0), draw.Src)
	// Torso
	draw.Draw(bodyImg, image.Rect(LaWidth, HelmHeight, LaWidth+TorsoWidth, HelmHeight+TorsoHeight), torsoImg, image.Pt(0, 0), draw.Src)
	// Left Arm
	draw.Draw(bodyImg, image.Rect(0, HelmHeight, LaWidth, HelmHeight+LaHeight), laImg, image.Pt(0, 0), draw.Src)
	// Right Arm
	draw.Draw(bodyImg, image.Rect(LaWidth+TorsoWidth, HelmHeight, LaWidth+TorsoWidth+RaWidth, HelmHeight+RaHeight), raImg, image.Pt(0, 0), draw.Src)
	// Left Leg
	draw.Draw(bodyImg, image.Rect(LaWidth, HelmHeight+TorsoHeight, LaWidth+LlWidth, HelmHeight+TorsoHeight+LlHeight), llImg, image.Pt(0, 0), draw.Src)
	// Right Leg
	draw.Draw(bodyImg, image.Rect(LaWidth+LlWidth, HelmHeight+TorsoHeight, LaWidth+LlWidth+RlWidth, HelmHeight+TorsoHeight+RlHeight), rlImg, image.Pt(0, 0), draw.Src)

	skin.Processed = bodyImg
	return nil
}

func (skin *mcSkin) GetBust() error {
	err := skin.GetBody()
	if err != nil {
		return err
	}

	skin.Processed = imaging.Crop(skin.Processed, image.Rect(0, 0, 16, 16))
	return nil
}

func (skin *mcSkin) WritePNG(w io.Writer) error {
	return png.Encode(w, skin.Processed)
}

func (skin *mcSkin) Resize(width uint) {
	skin.Processed = imaging.Resize(skin.Processed, int(width), 0, imaging.NearestNeighbor)
}

func cropHead(img image.Image) image.Image {
	return imaging.Crop(img, image.Rect(HeadX, HeadY, HeadX+HeadWidth, HeadY+HeadHeight))
}

func cropHelm(img image.Image) image.Image {
	headImg := cropHead(img)
	helmImg := imaging.Crop(img, image.Rect(HelmX, HelmY, HelmX+HelmWidth, HelmY+HelmHeight))

	sr := helmImg.Bounds()
	draw.Draw(helmImg, sr, helmImg, sr.Min, draw.Over)

	return headImg
}
<commit_msg>Re-implement more efficient GetBust<commit_after>package main

import (
	"github.com/disintegration/imaging"
	"github.com/minotar/minecraft"
	"image"
	"image/draw"
	"image/png"
	"io"
)

const (
	HeadX      = 8
	HeadY      = 8
	HeadWidth  = 8
	HeadHeight = 8

	HelmX      = 40
	HelmY      = 8
	HelmWidth  = 8
	HelmHeight = 8

	TorsoX      = 20
	TorsoY      = 20
	TorsoWidth  = 8
	TorsoHeight = 12

	RaX      = 44
	RaY      = 20
	RaWidth  = 4
	RaHeight = 12

	RlX      = 4
	RlY      = 20
	RlWidth  = 4
	RlHeight = 12

	LaX      = 36
	LaY      = 52
	LaWidth  = 4
	LaHeight = 12

	LlX      = 20
	LlY      = 52
	LlWidth  = 4
	LlHeight = 12

	// The height of the 'bust' relative to the width of the body (16)
	BustHeight = 16
)

type mcSkin struct {
	Processed image.Image
	minecraft.Skin
}

func (skin *mcSkin) GetHead() error {
	skin.Processed = cropHead(skin.Image)
	return nil
}

func (skin *mcSkin) GetHelm() error {
	skin.Processed = cropHelm(skin.Image)
	return nil
}

func (skin *mcSkin) GetBust() error {
	// Check if 1.8 skin (the max Y bound should be 64)
	render18Skin := true
	bounds := skin.Image.Bounds()
	if bounds.Max.Y != 64 {
		render18Skin = false
	}

	BustShift := BustHeight - HeadHeight

	helmImg := cropHelm(skin.Image)
	torsoImg := imaging.Crop(skin.Image, image.Rect(TorsoX, TorsoY, TorsoX+TorsoWidth, TorsoY+BustShift))
	raImg := imaging.Crop(skin.Image, image.Rect(RaX, RaY, RaX+RaWidth, RaY+BustShift))

	var laImg image.Image

	// If the skin is 1.8 then we will use the left arms and legs, otherwise flip the right ones and use them.
	if render18Skin {
		laImg = imaging.Crop(skin.Image, image.Rect(LaX, LaY, LaX+LaWidth, LaY+BustShift))
	} else {
		laImg = imaging.FlipH(raImg)
	}

	// Create a blank canvas for us to draw our bust on
	bustImg := image.NewRGBA(image.Rect(0, 0, LaWidth+TorsoWidth+RaWidth, BustHeight))
	// Helm
	draw.Draw(bustImg, image.Rect(LaWidth, 0, LaWidth+HelmWidth, HelmHeight), helmImg, image.Pt(0, 0), draw.Src)
	// Torso
	draw.Draw(bustImg, image.Rect(LaWidth, HelmHeight, LaWidth+TorsoWidth, BustHeight), torsoImg, image.Pt(0, 0), draw.Src)
	// Left Arm
	draw.Draw(bustImg, image.Rect(0, HelmHeight, LaWidth, BustHeight), laImg, image.Pt(0, 0), draw.Src)
	// Right Arm
	draw.Draw(bustImg, image.Rect(LaWidth+TorsoWidth, HelmHeight, LaWidth+TorsoWidth+RaWidth, BustHeight), raImg, image.Pt(0, 0), draw.Src)

	skin.Processed = bustImg
	return nil
}

func (skin *mcSkin) GetBody() error {
	// Check if 1.8 skin (the max Y bound should be 64)
	render18Skin := true
	bounds := skin.Image.Bounds()
	if bounds.Max.Y != 64 {
		render18Skin = false
	}

	helmImg := cropHelm(skin.Image)
	torsoImg := imaging.Crop(skin.Image, image.Rect(TorsoX, TorsoY, TorsoX+TorsoWidth, TorsoY+TorsoHeight))
	raImg := imaging.Crop(skin.Image, image.Rect(RaX, RaY, RaX+RaWidth, RaY+RaHeight))
	rlImg := imaging.Crop(skin.Image, image.Rect(RlX, RlY, RlX+RlWidth, RlY+RlHeight))

	var laImg, llImg image.Image

	// If the skin is 1.8 then we will use the left arms and legs, otherwise flip the right ones and use them.
	if render18Skin {
		laImg = imaging.Crop(skin.Image, image.Rect(LaX, LaY, LaX+LaWidth, LaY+LaHeight))
		llImg = imaging.Crop(skin.Image, image.Rect(LlX, LlY, LlX+LlWidth, LlY+LlHeight))
	} else {
		laImg = imaging.FlipH(raImg)

		llImg = imaging.FlipH(rlImg)
	}

	// Create a blank canvas for us to draw our body on
	bodyImg := image.NewRGBA(image.Rect(0, 0, LaWidth+TorsoWidth+RaWidth, HeadHeight+TorsoHeight+LlHeight))
	// Helm
	draw.Draw(bodyImg, image.Rect(LaWidth, 0, LaWidth+HelmWidth, HelmHeight), helmImg, image.Pt(0, 0), draw.Src)
	// Torso
	draw.Draw(bodyImg, image.Rect(LaWidth, HelmHeight, LaWidth+TorsoWidth, HelmHeight+TorsoHeight), torsoImg, image.Pt(0, 0), draw.Src)
	// Left Arm
	draw.Draw(bodyImg, image.Rect(0, HelmHeight, LaWidth, HelmHeight+LaHeight), laImg, image.Pt(0, 0), draw.Src)
	// Right Arm
	draw.Draw(bodyImg, image.Rect(LaWidth+TorsoWidth, HelmHeight, LaWidth+TorsoWidth+RaWidth, HelmHeight+RaHeight), raImg, image.Pt(0, 0), draw.Src)
	// Left Leg
	draw.Draw(bodyImg, image.Rect(LaWidth, HelmHeight+TorsoHeight, LaWidth+LlWidth, HelmHeight+TorsoHeight+LlHeight), llImg, image.Pt(0, 0), draw.Src)
	// Right Leg
	draw.Draw(bodyImg, image.Rect(LaWidth+LlWidth, HelmHeight+TorsoHeight, LaWidth+LlWidth+RlWidth, HelmHeight+TorsoHeight+RlHeight), rlImg, image.Pt(0, 0), draw.Src)

	skin.Processed = bodyImg
	return nil
}

func (skin *mcSkin) WritePNG(w io.Writer) error {
	return png.Encode(w, skin.Processed)
}

func (skin *mcSkin) Resize(width uint) {
	skin.Processed = imaging.Resize(skin.Processed, int(width), 0, imaging.NearestNeighbor)
}

func cropHead(img image.Image) image.Image {
	return imaging.Crop(img, image.Rect(HeadX, HeadY, HeadX+HeadWidth, HeadY+HeadHeight))
}

func cropHelm(img image.Image) image.Image {
	headImg := cropHead(img)
	helmImg := imaging.Crop(img, image.Rect(HelmX, HelmY, HelmX+HelmWidth, HelmY+HelmHeight))

	sr := helmImg.Bounds()
	draw.Draw(helmImg, sr, helmImg, sr.Min, draw.Over)

	return headImg
}
<|endoftext|>


<commit_before>// Package hyperloglog implements the HyperLogLog algorithm for
// cardinality estimation. In English: it counts things. It counts
// things using very small amounts of memory compared to the number of
// objects it is counting.
//
// For a full description of the algorithm, see the paper HyperLogLog:
// the analysis of a near-optimal cardinality estimation algorithm by
// Flajolet, et. al.
package hyperloglog

import (
	"fmt"
	"math"
)

var (
	exp32 = math.Pow(2, 32)
)

// A HyperLogLog is a deterministic cardinality estimator.  This version
// exports its fields so that it is suitable for saving eg. to a database.
type HyperLogLog struct {
	M         uint    // Number of registers
	B         uint32  // Number of bits used to determine register index
	Alpha     float64 // Bias correction constant
	Registers []uint8
}

// Compute bias correction alpha_m.
func getAlpha(m uint) (result float64) {
	switch m {
	case 16:
		result = 0.673
	case 32:
		result = 0.697
	case 64:
		result = 0.709
	default:
		result = 0.7213 / (1.0 + 1.079/float64(m))
	}
	return result
}

// New creates a HyperLogLog with the given number of registers. More
// registers leads to lower error in your estimated count, at the
// expense of memory.
//
// Choose a power of two number of registers, depending on the amount
// of memory you're willing to use and the error you're willing to
// tolerate. Each register uses one byte of memory.
//
// Standard error will be: σ ≈ 1.04 / sqrt(registers)
// The estimates provided by hyperloglog are expected to be within σ, 2σ, 3σ
// of the exact count in respectively 65%, 95%, 99% of all the cases.
func New(registers uint) (*HyperLogLog, error) {
	if (registers & (registers - 1)) != 0 {
		return nil, fmt.Errorf("number of registers %d not a power of two", registers)
	}
	h := &HyperLogLog{}
	h.M = registers
	h.B = uint32(math.Ceil(math.Log2(float64(registers))))
	h.Alpha = getAlpha(registers)
	h.Registers = make([]uint8, h.M)
	return h, nil
}

// Reset all internal variables and set the count to zero.
func (h *HyperLogLog) Reset() {
	for i := range h.Registers {
		h.Registers[i] = 0
	}
}

// Calculate the position of the leftmost 1-bit.
func rho(val uint32, max uint32) uint8 {
	r := uint32(1)
	for val&0x80000000 == 0 && r <= max {
		r++
		val <<= 1
	}
	return uint8(r)
}

// Add to the count. val should be a 32 bit unsigned integer from a
// good hash function.
func (h *HyperLogLog) Add(val uint32) {
	k := 32 - h.B
	r := rho(val<<h.B, k)
	j := val >> uint(k)
	if r > h.Registers[j] {
		h.Registers[j] = r
	}
}

// Count returns the estimated cardinality.
func (h *HyperLogLog) Count() uint64 {
	sum := 0.0
	m := float64(h.M)
	for _, val := range h.Registers {
		sum += 1.0 / math.Pow(2.0, float64(val))
	}
	estimate := h.Alpha * m * m / sum
	if estimate <= 5.0/2.0*m {
		// Small range correction
		v := 0
		for _, r := range h.Registers {
			if r == 0 {
				v++
			}
		}
		if v > 0 {
			estimate = m * math.Log(m/float64(v))
		}
	} else if estimate > 1.0/30.0*exp32 {
		// Large range correction
		estimate = -exp32 * math.Log(1-estimate/exp32)
	}
	return uint64(estimate)
}

// Merge another HyperLogLog into this one. The number of registers in
// each must be the same.
func (h *HyperLogLog) Merge(other *HyperLogLog) error {
	if h.M != other.M {
		return fmt.Errorf("number of registers doesn't match: %d != %d",
			h.M, other.M)
	}
	for j, r := range other.Registers {
		if r > h.Registers[j] {
			h.Registers[j] = r
		}
	}
	return nil
}
<commit_msg> Disable large-range correction<commit_after>// Package hyperloglog implements the HyperLogLog algorithm for
// cardinality estimation. In English: it counts things. It counts
// things using very small amounts of memory compared to the number of
// objects it is counting.
//
// For a full description of the algorithm, see the paper HyperLogLog:
// the analysis of a near-optimal cardinality estimation algorithm by
// Flajolet, et. al.
package hyperloglog

import (
	"fmt"
	"math"
)

var (
	exp32 = math.Pow(2, 32)
)

// A HyperLogLog is a deterministic cardinality estimator.  This version
// exports its fields so that it is suitable for saving eg. to a database.
type HyperLogLog struct {
	M         uint    // Number of registers
	B         uint32  // Number of bits used to determine register index
	Alpha     float64 // Bias correction constant
	Registers []uint8
}

// Compute bias correction alpha_m.
func getAlpha(m uint) (result float64) {
	switch m {
	case 16:
		result = 0.673
	case 32:
		result = 0.697
	case 64:
		result = 0.709
	default:
		result = 0.7213 / (1.0 + 1.079/float64(m))
	}
	return result
}

// New creates a HyperLogLog with the given number of registers. More
// registers leads to lower error in your estimated count, at the
// expense of memory.
//
// Choose a power of two number of registers, depending on the amount
// of memory you're willing to use and the error you're willing to
// tolerate. Each register uses one byte of memory.
//
// Standard error will be: σ ≈ 1.04 / sqrt(registers)
// The estimates provided by hyperloglog are expected to be within σ, 2σ, 3σ
// of the exact count in respectively 65%, 95%, 99% of all the cases.
func New(registers uint) (*HyperLogLog, error) {
	if (registers & (registers - 1)) != 0 {
		return nil, fmt.Errorf("number of registers %d not a power of two", registers)
	}
	h := &HyperLogLog{}
	h.M = registers
	h.B = uint32(math.Ceil(math.Log2(float64(registers))))
	h.Alpha = getAlpha(registers)
	h.Registers = make([]uint8, h.M)
	return h, nil
}

// Reset all internal variables and set the count to zero.
func (h *HyperLogLog) Reset() {
	for i := range h.Registers {
		h.Registers[i] = 0
	}
}

// Calculate the position of the leftmost 1-bit.
func rho(val uint32, max uint32) uint8 {
	r := uint32(1)
	for val&0x80000000 == 0 && r <= max {
		r++
		val <<= 1
	}
	return uint8(r)
}

// Add to the count. val should be a 32 bit unsigned integer from a
// good hash function.
func (h *HyperLogLog) Add(val uint32) {
	k := 32 - h.B
	r := rho(val<<h.B, k)
	j := val >> uint(k)
	if r > h.Registers[j] {
		h.Registers[j] = r
	}
}

// Count returns the estimated cardinality.
func (h *HyperLogLog) Count() uint64 {
	sum := 0.0
	m := float64(h.M)
	for _, val := range h.Registers {
		sum += 1.0 / math.Pow(2.0, float64(val))
	}
	estimate := h.Alpha * m * m / sum
	if estimate <= 5.0/2.0*m {
		// Small range correction
		v := 0
		for _, r := range h.Registers {
			if r == 0 {
				v++
			}
		}
		if v > 0 {
			estimate = m * math.Log(m/float64(v))
		}
	}
	// Not applying the large range correction proposed by Flajolet et al. as it leads to
	// significant overcounting. See https://github.com/DataDog/hyperloglog/pull/15
	return uint64(estimate)
}

// Merge another HyperLogLog into this one. The number of registers in
// each must be the same.
func (h *HyperLogLog) Merge(other *HyperLogLog) error {
	if h.M != other.M {
		return fmt.Errorf("number of registers doesn't match: %d != %d",
			h.M, other.M)
	}
	for j, r := range other.Registers {
		if r > h.Registers[j] {
			h.Registers[j] = r
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package isumm

import (
	"fmt"
	"sort"
	"strconv"
	"strings"
	"time"
)

const (
	opEntityName = "Operation"
)

type OpType int

const (
	Unknown = iota
	Balance
	Deposit
	Withdrawal
)

func (t OpType) String() string {
	switch t {
	case 1:
		return "Balance"
	case 2:
		return "Deposit"
	case 3:
		return "Withdrawal"
	}
	return "Unknown"
}

func (t OpType) IsValid() bool {
	return t.String() != "Unknown"
}

type Operation struct {
	Value     float32 `datastore:"value,noindex"`
	Type      OpType  `datastore:"type"`
	Timestamp int64   `datastore:"date"`
}

// TODO(danielfireman): Verify if the date needs to be cached.
func (o *Operation) Date() time.Time {
	return time.Unix(0, o.Timestamp)
}

func (o *Operation) SetDate(d time.Time) {
	o.Timestamp = d.UnixNano()
}

func NewOperation(t OpType, v float32, d time.Time) Operation {
	return Operation{Type: t, Value: v, Timestamp: d.UnixNano()}
}

func NewOperationFromString(t, v, d string) (Operation, error) {
	opTypeInt, err := strconv.Atoi(t)
	if err != nil {
		return Operation{}, fmt.Errorf("Invalid operation type: \"%s\"", t)
	}
	opType := OpType(opTypeInt)
	if !opType.IsValid() {
		return Operation{}, fmt.Errorf("Invalid operation type: \"%s\"", t)
	}
	value, err := strconv.ParseFloat(strings.TrimSpace(v), 32)
	if err != nil {
		return Operation{}, fmt.Errorf("Invalid value: \"%s\"", v)
	}
	date, err := time.Parse("2006-01-02", d)
	if err != nil {
		return Operation{}, fmt.Errorf("Invalid operation date: %s", d)
	}
	return Operation{Timestamp: date.UnixNano(), Value: float32(value), Type: opType}, nil
}

type Operations []Operation

func (ops Operations) Len() int {
	return len(ops)
}

func (ops Operations) Less(i, j int) bool {
	return ops[i].Timestamp > ops[j].Timestamp
}

func (ops Operations) Swap(i, j int) {
	ops[i], ops[j] = ops[j], ops[i]
}

type SummaryOp struct {
	Index     int
	Operation Operation
}

type Summary struct {
	Date       time.Time
	Balance    float32
	Change     float32
	SummaryOps []SummaryOp
}

func (s *Summary) Reset() {
	s.Balance = 0
	s.Change = 0
	s.SummaryOps = nil
}

type Summaries []Summary

func (s Summaries) Len() int {
	return len(s)
}

func (s Summaries) Less(i, j int) bool {
	return s[i].Date.Before(s[j].Date)
}

func (s Summaries) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}

func (ops Operations) Summarize() Summaries {
	if !sort.IsSorted(ops) {
		sort.Sort(ops)
	}
	var returned []Summary
	var summ Summary
	for i, op := range ops {
		// If the month has changed (please notice that ops are sorted by
		// month).
		if i > 0 && ops[i-1].Date().Month() != op.Date().Month() {
			returned = append(returned, summ)
			summ.Reset()
		}
		// At this point we are only interested on the month/year pair and
		// would like to enjoy the datetime goodies and format (flot and
		// other libraries support it natively). So, setting the day to
		// the first day of the month.
		summ.Date = monthYear(op.Date())
		switch op.Type {
		case Withdrawal:
			summ.Change -= op.Value
		case Deposit:
			summ.Change += op.Value
		case Balance:
			// This enforces the case when we have more than one balance, the
			// system will use the most recent. This is easier than change
			// loads of places to make sure enforce only one balance.
			if summ.Balance == 0 {
				summ.Balance = op.Value
			}
		}
		// We aggregate the operations for that month as part of the Operations
		// field, which allows us to show a nice log of everything affecting that
		// month.
		summ.SummaryOps = append(summ.SummaryOps, SummaryOp{Index: i, Operation: op})
	}
	// We must not forget the latest summary.
	if len(ops) > 0 {
		returned = append(returned, summ)
	}
	return returned
}

func monthYear(t time.Time) time.Time {
	return time.Date(t.Year(), t.Month(), 01, 0, 0, 0, 0, t.Location())
}
<commit_msg>Moving some statements so they're grouped with similar operations. (pull 		request code-review)<commit_after>package isumm

import (
	"fmt"
	"sort"
	"strconv"
	"strings"
	"time"
)

const (
	opEntityName = "Operation"
)

type OpType int

const (
	Unknown = iota
	Balance
	Deposit
	Withdrawal
)

func (t OpType) String() string {
	switch t {
	case 1:
		return "Balance"
	case 2:
		return "Deposit"
	case 3:
		return "Withdrawal"
	}
	return "Unknown"
}

func (t OpType) IsValid() bool {
	return t.String() != "Unknown"
}

type Operation struct {
	Value     float32 `datastore:"value,noindex"`
	Type      OpType  `datastore:"type"`
	Timestamp int64   `datastore:"date"`
}

// TODO(danielfireman): Verify if the date needs to be cached.
func (o *Operation) Date() time.Time {
	return time.Unix(0, o.Timestamp)
}

func (o *Operation) SetDate(d time.Time) {
	o.Timestamp = d.UnixNano()
}

func NewOperation(t OpType, v float32, d time.Time) Operation {
	return Operation{Type: t, Value: v, Timestamp: d.UnixNano()}
}

func NewOperationFromString(t, v, d string) (Operation, error) {
	opTypeInt, err := strconv.Atoi(t)
	if err != nil {
		return Operation{}, fmt.Errorf("Invalid operation type: \"%s\"", t)
	}
	opType := OpType(opTypeInt)
	if !opType.IsValid() {
		return Operation{}, fmt.Errorf("Invalid operation type: \"%s\"", t)
	}
	value, err := strconv.ParseFloat(strings.TrimSpace(v), 32)
	if err != nil {
		return Operation{}, fmt.Errorf("Invalid value: \"%s\"", v)
	}
	date, err := time.Parse("2006-01-02", d)
	if err != nil {
		return Operation{}, fmt.Errorf("Invalid operation date: %s", d)
	}
	return Operation{Timestamp: date.UnixNano(), Value: float32(value), Type: opType}, nil
}

type Operations []Operation

func (ops Operations) Len() int {
	return len(ops)
}

func (ops Operations) Less(i, j int) bool {
	return ops[i].Timestamp > ops[j].Timestamp
}

func (ops Operations) Swap(i, j int) {
	ops[i], ops[j] = ops[j], ops[i]
}

type SummaryOp struct {
	Index     int
	Operation Operation
}

type Summary struct {
	Date       time.Time
	Balance    float32
	Change     float32
	SummaryOps []SummaryOp
}

func (s *Summary) Reset() {
	s.Balance = 0
	s.Change = 0
	s.SummaryOps = nil
}

type Summaries []Summary

func (s Summaries) Len() int {
	return len(s)
}

func (s Summaries) Less(i, j int) bool {
	return s[i].Date.Before(s[j].Date)
}

func (s Summaries) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}

func (ops Operations) Summarize() Summaries {
	if !sort.IsSorted(ops) {
		sort.Sort(ops)
	}
	var returned []Summary
	var summ Summary
	for i, op := range ops {
		// If the month has changed (please notice that ops are sorted by
		// month).
		if i > 0 && ops[i-1].Date().Month() != op.Date().Month() {
			returned = append(returned, summ)
			summ.Reset()
		}
		// At this point we are only interested on the month/year pair and
		// would like to enjoy the datetime goodies and format (flot and
		// other libraries support it natively). So, setting the day to
		// the first day of the month.
		summ.Date = monthYear(op.Date())
		// We aggregate the operations for that month as part of the Operations
		// field, which allows us to show a nice log of everything affecting that
		// month.
		summ.SummaryOps = append(summ.SummaryOps, SummaryOp{Index: i, Operation: op})
		switch op.Type {
		case Withdrawal:
			summ.Change -= op.Value
		case Deposit:
			summ.Change += op.Value
		case Balance:
			// This enforces the case when we have more than one balance, the
			// system will use the most recent. This is easier than change
			// loads of places to make sure enforce only one balance.
			if summ.Balance == 0 {
				summ.Balance = op.Value
			}
		}
	}
	// We must not forget the latest summary.
	if len(ops) > 0 {
		returned = append(returned, summ)
	}
	return returned
}

func monthYear(t time.Time) time.Time {
	return time.Date(t.Year(), t.Month(), 01, 0, 0, 0, 0, t.Location())
}
<|endoftext|>