<commit_before>// Copyright (c) 2019-2020 Tigera, Inc. All rights reserved.
//
// 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 bpf

import (
	"encoding/json"
	"fmt"
	"os"
	"os/exec"
	"strconv"
	"strings"

	"golang.org/x/sys/unix"

	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
)

type MapIter func(k, v []byte)

type Map interface {
	GetName() string
	// EnsureExists opens the map, creating and pinning it if needed.
	EnsureExists() error
	// MapFD gets the file descriptor of the map, only valid after calling EnsureExists().
	MapFD() MapFD
	// Path returns the path that the map is (to be) pinned to.
	Path() string

	Iter(MapIter) error
	Update(k, v []byte) error
	Get(k []byte) ([]byte, error)
	Delete(k []byte) error
}

type MapParameters struct {
	Filename   string
	Type       string
	KeySize    int
	ValueSize  int
	MaxEntries int
	Name       string
	Flags      int
	Version    int
}

func versionedStr(ver int, str string) string {
	if ver <= 1 {
		return str
	}

	return fmt.Sprintf("%s%d", str, ver)
}

func (mp *MapParameters) versionedName() string {
	return versionedStr(mp.Version, mp.Name)
}

func (mp *MapParameters) versionedFilename() string {
	return versionedStr(mp.Version, mp.Filename)
}

type MapContext struct {
	RepinningEnabled bool
}

func (c *MapContext) NewPinnedMap(params MapParameters) Map {
	if len(params.versionedName()) >= unix.BPF_OBJ_NAME_LEN {
		logrus.WithField("name", params.Name).Panic("Bug: BPF map name too long")
	}
	m := &PinnedMap{
		context:       c,
		MapParameters: params,
		perCPU:        strings.Contains(params.Type, "percpu"),
	}
	return m
}

type PinnedMap struct {
	context *MapContext
	MapParameters

	fdLoaded bool
	fd       MapFD
	perCPU   bool
}

func (b *PinnedMap) GetName() string {
	return b.versionedName()
}

func (b *PinnedMap) MapFD() MapFD {
	if !b.fdLoaded {
		logrus.Panic("MapFD() called without first calling EnsureExists()")
	}
	return b.fd
}

func (b *PinnedMap) Path() string {
	return b.versionedFilename()
}

func (b *PinnedMap) Close() error {
	err := b.fd.Close()
	b.fdLoaded = false
	b.fd = 0
	return err
}

func (b *PinnedMap) RepinningEnabled() bool {
	if b.context == nil {
		return false
	}
	return b.context.RepinningEnabled
}

// DumpMapCmd returns the command that can be used to dump a map or an error
func DumpMapCmd(m Map) ([]string, error) {
	if pm, ok := m.(*PinnedMap); ok {
		return []string{
			"bpftool",
			"--json",
			"--pretty",
			"map",
			"dump",
			"pinned",
			pm.versionedFilename(),
		}, nil
	}

	return nil, errors.Errorf("unrecognized map type %T", m)
}

// IterMapCmdOutput iterates over the outout of a command obtained by DumpMapCmd
func IterMapCmdOutput(output []byte, f MapIter) error {
	var mp []mapEntry
	err := json.Unmarshal(output, &mp)
	if err != nil {
		return errors.Errorf("cannot parse json output: %v\n%s", err, output)
	}

	for _, me := range mp {
		k, err := hexStringsToBytes(me.Key)
		if err != nil {
			return errors.Errorf("failed parsing entry %s key: %e", me, err)
		}
		v, err := hexStringsToBytes(me.Value)
		if err != nil {
			return errors.Errorf("failed parsing entry %s val: %e", me, err)
		}
		f(k, v)
	}

	return nil
}

func (b *PinnedMap) Iter(f MapIter) error {
	cmd, err := DumpMapCmd(b)
	if err != nil {
		return err
	}

	prog := cmd[0]
	args := cmd[1:]

	printCommand(prog, args...)
	output, err := exec.Command(prog, args...).CombinedOutput()
	if err != nil {
		return errors.Errorf("failed to dump in map (%s): %s\n%s", b.versionedFilename(), err, output)
	}

	if err := IterMapCmdOutput(output, f); err != nil {
		return errors.WithMessagef(err, "map %s", b.versionedFilename())
	}

	return nil
}

func (b *PinnedMap) Update(k, v []byte) error {
	if b.perCPU {
		// Per-CPU maps need a buffer of value-size * num-CPUs.
		logrus.Panic("Per-CPU operations not implemented")
	}
	return UpdateMapEntry(b.fd, k, v)
}

func (b *PinnedMap) Get(k []byte) ([]byte, error) {
	if b.perCPU {
		// Per-CPU maps need a buffer of value-size * num-CPUs.
		logrus.Panic("Per-CPU operations not implemented")
	}
	return GetMapEntry(b.fd, k, b.ValueSize)
}

func appendBytes(strings []string, bytes []byte) []string {
	for _, b := range bytes {
		strings = append(strings, strconv.FormatInt(int64(b), 10))
	}
	return strings
}

func (b *PinnedMap) Delete(k []byte) error {
	logrus.WithField("key", k).Debug("Deleting map entry")
	args := make([]string, 0, 10+len(k))
	args = append(args, "map", "delete",
		"pinned", b.versionedFilename(),
		"key")
	args = appendBytes(args, k)

	cmd := exec.Command("bpftool", args...)
	out, err := cmd.CombinedOutput()
	if err != nil {
		if strings.Contains(string(out), "No such file or directory") {
			// Check that the error wasn't about the map as a whole being missing.
			if _, statErr := os.Stat(b.versionedFilename()); statErr == nil {
				// We expect failures due to the entry being missing, return a dedicated error
				// and avoid logging a scary warning.
				logrus.WithField("k", k).Debug("Item didn't exist.")
				return os.ErrNotExist
			}
		}
		logrus.WithField("out", string(out)).Error("Failed to run bpftool")
	}
	return err
}

func (b *PinnedMap) EnsureExists() error {
	if b.fdLoaded {
		return nil
	}

	_, err := MaybeMountBPFfs()
	if err != nil {
		logrus.WithError(err).Error("Failed to mount bpffs")
		return err
	}
	// FIXME hard-coded dir
	err = os.MkdirAll("/sys/fs/bpf/tc/globals", 0700)
	if err != nil {
		logrus.WithError(err).Error("Failed create dir")
		return err
	}

	_, err = os.Stat(b.versionedFilename())
	if err != nil {
		if !os.IsNotExist(err) {
			return err
		}
		logrus.Debug("Map file didn't exist")
		if b.context.RepinningEnabled {
			logrus.WithField("name", b.Name).Info("Looking for map by name (to repin it)")
			err = RepinMap(b.versionedName(), b.versionedFilename())
			if err != nil && !os.IsNotExist(err) {
				return err
			}
		}
	}

	if err == nil {
		logrus.Debug("Map file already exists, trying to open it")
		b.fd, err = GetMapFDByPin(b.versionedFilename())
		if err == nil {
			b.fdLoaded = true
			logrus.WithField("fd", b.fd).WithField("name", b.versionedFilename()).
				Info("Loaded map file descriptor.")
		}
		return err
	}

	logrus.Debug("Map didn't exist, creating it")
	cmd := exec.Command("bpftool", "map", "create", b.versionedFilename(),
		"type", b.Type,
		"key", fmt.Sprint(b.KeySize),
		"value", fmt.Sprint(b.ValueSize),
		"entries", fmt.Sprint(b.MaxEntries),
		"name", b.versionedName(),
		"flags", fmt.Sprint(b.Flags),
	)
	out, err := cmd.CombinedOutput()
	if err != nil {
		logrus.WithField("out", string(out)).Error("Failed to run bpftool")
		return err
	}
	b.fd, err = GetMapFDByPin(b.versionedFilename())
	if err == nil {
		b.fdLoaded = true
		logrus.WithField("fd", b.fd).WithField("name", b.versionedFilename()).
			Info("Loaded map file descriptor.")
	}
	return err
}

type bpftoolMapMeta struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
}

func RepinMap(name string, filename string) error {
	cmd := exec.Command("bpftool", "map", "list", "-j")
	out, err := cmd.Output()
	if err != nil {
		return errors.Wrap(err, "bpftool map list failed")
	}
	logrus.WithField("maps", string(out)).Debug("Got map metadata.")

	var maps []bpftoolMapMeta
	err = json.Unmarshal(out, &maps)
	if err != nil {
		return errors.Wrap(err, "bpftool returned bad JSON")
	}

	for _, m := range maps {
		if m.Name == name {
			// Found the map, try to repin it.
			cmd := exec.Command("bpftool", "map", "pin", "id", fmt.Sprint(m.ID), filename)
			return errors.Wrap(cmd.Run(), "bpftool failed to repin map")
		}
	}

	return os.ErrNotExist
}
<commit_msg>Markups<commit_after>// Copyright (c) 2019-2020 Tigera, Inc. All rights reserved.
//
// 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 bpf

import (
	"encoding/json"
	"fmt"
	"os"
	"os/exec"
	"strconv"
	"strings"

	"golang.org/x/sys/unix"

	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
)

type MapIter func(k, v []byte)

type Map interface {
	GetName() string
	// EnsureExists opens the map, creating and pinning it if needed.
	EnsureExists() error
	// MapFD gets the file descriptor of the map, only valid after calling EnsureExists().
	MapFD() MapFD
	// Path returns the path that the map is (to be) pinned to.
	Path() string

	Iter(MapIter) error
	Update(k, v []byte) error
	Get(k []byte) ([]byte, error)
	Delete(k []byte) error
}

type MapParameters struct {
	Filename   string
	Type       string
	KeySize    int
	ValueSize  int
	MaxEntries int
	Name       string
	Flags      int
	Version    int
}

func versionedStr(ver int, str string) string {
	if ver <= 1 {
		return str
	}

	return fmt.Sprintf("%s%d", str, ver)
}

func (mp *MapParameters) versionedName() string {
	return versionedStr(mp.Version, mp.Name)
}

func (mp *MapParameters) versionedFilename() string {
	return versionedStr(mp.Version, mp.Filename)
}

type MapContext struct {
	RepinningEnabled bool
}

func (c *MapContext) NewPinnedMap(params MapParameters) Map {
	if len(params.versionedName()) >= unix.BPF_OBJ_NAME_LEN {
		logrus.WithField("name", params.Name).Panic("Bug: BPF map name too long")
	}
	m := &PinnedMap{
		context:       c,
		MapParameters: params,
		perCPU:        strings.Contains(params.Type, "percpu"),
	}
	return m
}

type PinnedMap struct {
	context *MapContext
	MapParameters

	fdLoaded bool
	fd       MapFD
	perCPU   bool
}

func (b *PinnedMap) GetName() string {
	return b.versionedName()
}

func (b *PinnedMap) MapFD() MapFD {
	if !b.fdLoaded {
		logrus.Panic("MapFD() called without first calling EnsureExists()")
	}
	return b.fd
}

func (b *PinnedMap) Path() string {
	return b.versionedFilename()
}

func (b *PinnedMap) Close() error {
	err := b.fd.Close()
	b.fdLoaded = false
	b.fd = 0
	return err
}

func (b *PinnedMap) RepinningEnabled() bool {
	if b.context == nil {
		return false
	}
	return b.context.RepinningEnabled
}

// DumpMapCmd returns the command that can be used to dump a map or an error
func DumpMapCmd(m Map) ([]string, error) {
	if pm, ok := m.(*PinnedMap); ok {
		return []string{
			"bpftool",
			"--json",
			"--pretty",
			"map",
			"dump",
			"pinned",
			pm.versionedFilename(),
		}, nil
	}

	return nil, errors.Errorf("unrecognized map type %T", m)
}

// IterMapCmdOutput iterates over the outout of a command obtained by DumpMapCmd
func IterMapCmdOutput(output []byte, f MapIter) error {
	var mp []mapEntry
	err := json.Unmarshal(output, &mp)
	if err != nil {
		return errors.Errorf("cannot parse json output: %v\n%s", err, output)
	}

	for _, me := range mp {
		k, err := hexStringsToBytes(me.Key)
		if err != nil {
			return errors.Errorf("failed parsing entry %s key: %e", me, err)
		}
		v, err := hexStringsToBytes(me.Value)
		if err != nil {
			return errors.Errorf("failed parsing entry %s val: %e", me, err)
		}
		f(k, v)
	}

	return nil
}

func (b *PinnedMap) Iter(f MapIter) error {
	cmd, err := DumpMapCmd(b)
	if err != nil {
		return err
	}

	prog := cmd[0]
	args := cmd[1:]

	printCommand(prog, args...)
	output, err := exec.Command(prog, args...).CombinedOutput()
	if err != nil {
		return errors.Errorf("failed to dump in map (%s): %s\n%s", b.versionedFilename(), err, output)
	}

	if err := IterMapCmdOutput(output, f); err != nil {
		return errors.WithMessagef(err, "map %s", b.versionedFilename())
	}

	return nil
}

func (b *PinnedMap) Update(k, v []byte) error {
	if b.perCPU {
		// Per-CPU maps need a buffer of value-size * num-CPUs.
		logrus.Panic("Per-CPU operations not implemented")
	}
	return UpdateMapEntry(b.fd, k, v)
}

func (b *PinnedMap) Get(k []byte) ([]byte, error) {
	if b.perCPU {
		// Per-CPU maps need a buffer of value-size * num-CPUs.
		logrus.Panic("Per-CPU operations not implemented")
	}
	return GetMapEntry(b.fd, k, b.ValueSize)
}

func appendBytes(strings []string, bytes []byte) []string {
	for _, b := range bytes {
		strings = append(strings, strconv.FormatInt(int64(b), 10))
	}
	return strings
}

func (b *PinnedMap) Delete(k []byte) error {
	logrus.WithField("key", k).Debug("Deleting map entry")
	args := make([]string, 0, 10+len(k))
	args = append(args, "map", "delete",
		"pinned", b.versionedFilename(),
		"key")
	args = appendBytes(args, k)

	cmd := exec.Command("bpftool", args...)
	out, err := cmd.CombinedOutput()
	if err != nil {
		if strings.Contains(string(out), "delete failed: No such file or directory") {
			logrus.WithField("k", k).Debug("Item didn't exist.")
			return os.ErrNotExist
		}
		logrus.WithField("out", string(out)).Error("Failed to run bpftool")
	}
	return err
}

func (b *PinnedMap) EnsureExists() error {
	if b.fdLoaded {
		return nil
	}

	_, err := MaybeMountBPFfs()
	if err != nil {
		logrus.WithError(err).Error("Failed to mount bpffs")
		return err
	}
	// FIXME hard-coded dir
	err = os.MkdirAll("/sys/fs/bpf/tc/globals", 0700)
	if err != nil {
		logrus.WithError(err).Error("Failed create dir")
		return err
	}

	_, err = os.Stat(b.versionedFilename())
	if err != nil {
		if !os.IsNotExist(err) {
			return err
		}
		logrus.Debug("Map file didn't exist")
		if b.context.RepinningEnabled {
			logrus.WithField("name", b.Name).Info("Looking for map by name (to repin it)")
			err = RepinMap(b.versionedName(), b.versionedFilename())
			if err != nil && !os.IsNotExist(err) {
				return err
			}
		}
	}

	if err == nil {
		logrus.Debug("Map file already exists, trying to open it")
		b.fd, err = GetMapFDByPin(b.versionedFilename())
		if err == nil {
			b.fdLoaded = true
			logrus.WithField("fd", b.fd).WithField("name", b.versionedFilename()).
				Info("Loaded map file descriptor.")
		}
		return err
	}

	logrus.Debug("Map didn't exist, creating it")
	cmd := exec.Command("bpftool", "map", "create", b.versionedFilename(),
		"type", b.Type,
		"key", fmt.Sprint(b.KeySize),
		"value", fmt.Sprint(b.ValueSize),
		"entries", fmt.Sprint(b.MaxEntries),
		"name", b.versionedName(),
		"flags", fmt.Sprint(b.Flags),
	)
	out, err := cmd.CombinedOutput()
	if err != nil {
		logrus.WithField("out", string(out)).Error("Failed to run bpftool")
		return err
	}
	b.fd, err = GetMapFDByPin(b.versionedFilename())
	if err == nil {
		b.fdLoaded = true
		logrus.WithField("fd", b.fd).WithField("name", b.versionedFilename()).
			Info("Loaded map file descriptor.")
	}
	return err
}

type bpftoolMapMeta struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
}

func RepinMap(name string, filename string) error {
	cmd := exec.Command("bpftool", "map", "list", "-j")
	out, err := cmd.Output()
	if err != nil {
		return errors.Wrap(err, "bpftool map list failed")
	}
	logrus.WithField("maps", string(out)).Debug("Got map metadata.")

	var maps []bpftoolMapMeta
	err = json.Unmarshal(out, &maps)
	if err != nil {
		return errors.Wrap(err, "bpftool returned bad JSON")
	}

	for _, m := range maps {
		if m.Name == name {
			// Found the map, try to repin it.
			cmd := exec.Command("bpftool", "map", "pin", "id", fmt.Sprint(m.ID), filename)
			return errors.Wrap(cmd.Run(), "bpftool failed to repin map")
		}
	}

	return os.ErrNotExist
}
<|endoftext|>


<commit_before>// Updated automatically (altered manually just prior to each release)

package main

const appVersion = "v0.42.0"
<commit_msg>v0.43.0<commit_after>// Updated automatically (altered manually just prior to each release)

package main

const appVersion = "v0.43.0"
<|endoftext|>


<commit_before>package pilosa
const Version = "v0.8.0-16-g46c8a62"<commit_msg>updated version<commit_after>package pilosa

const Version = "v0.10.0"
<|endoftext|>


<commit_before>package sorg

const (
	// Release is the asset version of the site. Bump when any assets are
	// updated to blow away any browser caches.
	Release = "55"
)
<commit_msg>Bump asset version<commit_after>package sorg

const (
	// Release is the asset version of the site. Bump when any assets are
	// updated to blow away any browser caches.
	Release = "56"
)
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"os"
	"os/exec"
	path "path/filepath"
	"regexp"
)

var cmdVersion = &Command{
	UsageLine: "version",
	Short:     "show the Bee, Beego and Go version",
	Long: `
show the Bee, Beego and Go version

bee version
    bee   :1.2.3
    beego :1.4.2
    Go    :go version go1.3.3 linux/amd64

`,
}

func init() {
	cmdVersion.Run = versionCmd
}

func versionCmd(cmd *Command, args []string) int {
	fmt.Println("bee   :" + version)
	fmt.Println("beego :" + getbeegoVersion())
	//fmt.Println("Go    :" + runtime.Version())
	goversion, err := exec.Command("go", "version").Output()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Go    :" + string(goversion))
	return 0
}

func getbeegoVersion() string {
	gopath := os.Getenv("GOPATH")
	re, err := regexp.Compile(`const VERSION = "([0-9.]+)"`)
	if err != nil {
		return ""
	}
	if gopath == "" {
		err = fmt.Errorf("you should set GOPATH in the env")
		return ""
	}
	wgopath := path.SplitList(gopath)
	for _, wg := range wgopath {
		wg, _ = path.EvalSymlinks(path.Join(wg, "src", "github.com", "astaxie", "beego"))
		filename := path.Join(wg, "beego.go")
		_, err := os.Stat(filename)
		if err != nil {
			if os.IsNotExist(err) {
				continue
			}
			ColorLog("[ERRO] get beego.go has error\n")
		}
		fd, err := os.Open(filename)
		if err != nil {
			ColorLog("[ERRO] open beego.go has error\n")
			continue
		}
		reader := bufio.NewReader(fd)
		for {
			byteLine, _, er := reader.ReadLine()
			if er != nil && er != io.EOF {
				return ""
			}
			if er == io.EOF {
				break
			}
			line := string(byteLine)
			s := re.FindStringSubmatch(line)
			if len(s) >= 2 {
				return s[1]
			}
		}

	}
	return "you don't install beego,install first: github.com/astaxie/beego"
}
<commit_msg>fix the beego version<commit_after>package main

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"os"
	"os/exec"
	path "path/filepath"
	"regexp"
)

var cmdVersion = &Command{
	UsageLine: "version",
	Short:     "show the Bee, Beego and Go version",
	Long: `
show the Bee, Beego and Go version

bee version
    bee   :1.2.3
    beego :1.4.2
    Go    :go version go1.3.3 linux/amd64

`,
}

func init() {
	cmdVersion.Run = versionCmd
}

func versionCmd(cmd *Command, args []string) int {
	fmt.Println("bee   :" + version)
	fmt.Println("beego :" + getbeegoVersion())
	//fmt.Println("Go    :" + runtime.Version())
	goversion, err := exec.Command("go", "version").Output()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Go    :" + string(goversion))
	return 0
}

func getbeegoVersion() string {
	gopath := os.Getenv("GOPATH")
	re, err := regexp.Compile(`VERSION = "([0-9.]+)"`)
	if err != nil {
		return ""
	}
	if gopath == "" {
		err = fmt.Errorf("you should set GOPATH in the env")
		return ""
	}
	wgopath := path.SplitList(gopath)
	for _, wg := range wgopath {
		wg, _ = path.EvalSymlinks(path.Join(wg, "src", "github.com", "astaxie", "beego"))
		filename := path.Join(wg, "beego.go")
		_, err := os.Stat(filename)
		if err != nil {
			if os.IsNotExist(err) {
				continue
			}
			ColorLog("[ERRO] get beego.go has error\n")
		}
		fd, err := os.Open(filename)
		if err != nil {
			ColorLog("[ERRO] open beego.go has error\n")
			continue
		}
		reader := bufio.NewReader(fd)
		for {
			byteLine, _, er := reader.ReadLine()
			if er != nil && er != io.EOF {
				return ""
			}
			if er == io.EOF {
				break
			}
			line := string(byteLine)
			s := re.FindStringSubmatch(line)
			if len(s) >= 2 {
				return s[1]
			}
		}

	}
	return "you don't install beego,install first: github.com/astaxie/beego"
}
<|endoftext|>


<commit_before>// WARNING: auto-generated by Makefile release target -- run 'make release' to update

package main

const (
	Version     = "v0.3.2"
	GitCommit   = "59cf4a4"          // the commit JUST BEFORE the release
	VersionDate = "2020-11-23 23:26" // UTC
)
<commit_msg>v0.3.2 release<commit_after>// WARNING: auto-generated by Makefile release target -- run 'make release' to update

package main

const (
	Version = "v0.3.2"
	GitCommit = "76126a6" // the commit JUST BEFORE the release
	VersionDate = "2020-11-24 01:38" // UTC
)

<|endoftext|>


<commit_before>package main

// The git commit that was compiled. This will be filled in by the compiler.
var GitCommit string
var GitDescribe string

// The main version number that is being run at the moment.
const Version = "0.2.2"

// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
// such as "dev" (in development), "beta", "rc1", etc.
const VersionPrerelease = "dev"
<commit_msg>Removing the pre-release marker<commit_after>package main

// The git commit that was compiled. This will be filled in by the compiler.
var GitCommit string
var GitDescribe string

// The main version number that is being run at the moment.
const Version = "0.2.2"

// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
// such as "dev" (in development), "beta", "rc1", etc.
const VersionPrerelease = ""
<|endoftext|>


<commit_before>package sudoku

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

//The actual techniques are intialized in hs_techniques.go, and actually defined in hst_*.go files.
//Techniques is ALL technies. CheapTechniques is techniques that are reasonably cheap to compute.
//ExpensiveTechniques is techniques that should only be used if all else has failed.
var Techniques []SolveTechnique
var CheapTechniques []SolveTechnique
var ExpensiveTechniques []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 {
	//The cells that will be affected by the techinque
	TargetCells CellList
	//The cells that together lead the techinque to being valid
	PointerCells CellList
	//The numbers we will remove (or, in the case of Fill, add)
	//TODO: shouldn't this be renamed TargetNums?
	TargetNums IntSlice
	//The numbers in pointerCells that lead us to remove TargetNums from TargetCells.
	//This is only very rarely needed (at this time only for hiddenSubset techniques)
	PointerNums IntSlice
	//The general technique that underlies this step.
	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.TargetNums) == 0 {
			return false
		}
		cell := self.TargetCells[0].InGrid(grid)
		return self.TargetNums[0] != cell.Number()
	} else {
		useful := false
		for _, cell := range self.TargetCells {
			gridCell := cell.InGrid(grid)
			for _, exclude := range self.TargetNums {
				//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.TargetNums) == 0 {
			return
		}
		cell := self.TargetCells[0].InGrid(grid)
		cell.SetNumber(self.TargetNums[0])
	} else {
		for _, cell := range self.TargetCells {
			gridCell := cell.InGrid(grid)
			for _, exclude := range self.TargetNums {
				gridCell.setExcluded(exclude, true)
			}
		}
	}
}

func (self *SolveStep) Description() string {
	result := ""
	if self.Technique.IsFill() {
		result += fmt.Sprintf("We put %s in cell %s ", self.TargetNums.Description(), self.TargetCells.Description())
	} else {
		//TODO: pluralize based on length of lists.
		result += fmt.Sprintf("We remove the possibilities %s from cells %s ", self.TargetNums.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

	//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

		possibilities := runTechniques(CheapTechniques, self)

		//Now pick one to apply.
		if len(possibilities) == 0 {
			//Okay, let's try the ExpensiveTechniques, as a hail mary.
			possibilities = runTechniques(ExpensiveTechniques, self)
			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 runTechniques(techniques []SolveTechnique, grid *Grid) []*SolveStep {
	numTechniques := len(techniques)
	possibilitiesChan := make(chan []*SolveStep)

	var possibilities []*SolveStep

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

	//Collect all of the results
	for i := 0; i < numTechniques; i++ {
		for _, possibility := range <-possibilitiesChan {
			possibilities = append(possibilities, possibility)
		}
	}

	return possibilities
}

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>Add an (untested) debug summary() method to solveDirections<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.
//Techniques is ALL technies. CheapTechniques is techniques that are reasonably cheap to compute.
//ExpensiveTechniques is techniques that should only be used if all else has failed.
var Techniques []SolveTechnique
var CheapTechniques []SolveTechnique
var ExpensiveTechniques []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 {
	//The cells that will be affected by the techinque
	TargetCells CellList
	//The cells that together lead the techinque to being valid
	PointerCells CellList
	//The numbers we will remove (or, in the case of Fill, add)
	//TODO: shouldn't this be renamed TargetNums?
	TargetNums IntSlice
	//The numbers in pointerCells that lead us to remove TargetNums from TargetCells.
	//This is only very rarely needed (at this time only for hiddenSubset techniques)
	PointerNums IntSlice
	//The general technique that underlies this step.
	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.TargetNums) == 0 {
			return false
		}
		cell := self.TargetCells[0].InGrid(grid)
		return self.TargetNums[0] != cell.Number()
	} else {
		useful := false
		for _, cell := range self.TargetCells {
			gridCell := cell.InGrid(grid)
			for _, exclude := range self.TargetNums {
				//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.TargetNums) == 0 {
			return
		}
		cell := self.TargetCells[0].InGrid(grid)
		cell.SetNumber(self.TargetNums[0])
	} else {
		for _, cell := range self.TargetCells {
			gridCell := cell.InGrid(grid)
			for _, exclude := range self.TargetNums {
				gridCell.setExcluded(exclude, true)
			}
		}
	}
}

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

func (self SolveDirections) summary() string {
	//TODO: test this.
	techniqueCount := make(map[string]int)
	for _, step := range self {
		techniqueCount[step.Technique.Name()] += 1
	}
	return fmt.Sprint(techniqueCount)
}

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

	//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

		possibilities := runTechniques(CheapTechniques, self)

		//Now pick one to apply.
		if len(possibilities) == 0 {
			//Okay, let's try the ExpensiveTechniques, as a hail mary.
			possibilities = runTechniques(ExpensiveTechniques, self)
			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 runTechniques(techniques []SolveTechnique, grid *Grid) []*SolveStep {
	numTechniques := len(techniques)
	possibilitiesChan := make(chan []*SolveStep)

	var possibilities []*SolveStep

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

	//Collect all of the results
	for i := 0; i < numTechniques; i++ {
		for _, possibility := range <-possibilitiesChan {
			possibilities = append(possibilities, possibility)
		}
	}

	return possibilities
}

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 igener

import (
	"fmt"
	"hash/crc32"
	"os"
	"testing"
	"time"
)

func TestIGener(t *testing.T) {
	ig := NewIGener()
	var id string
	m := make(map[string]struct{})
	for i := 0; i < 10000; i++ {
		id = <-ig
		m[id] = struct{}{}
	}
	if len(m) != 10000 {
		t.Error("TestIGener Error")
	}
	t.Log("Test IGener PASS")
}

func TestMachinePidEncode(t *testing.T) {
	hostname, _ := os.Hostname()
	hashCode := crc32.ChecksumIEEE([]byte(hostname))
	machineCode := fmt.Sprintf("%06x", hashCode)
	pid := os.Getpid()
	pidCode := fmt.Sprintf("%04x", pid)

	ig := &IGener{
		second: time.Now().Unix(),
		inc:    0,
		idChan: make(chan string),
	}

	machineCodeFromIg, pidCodeFromIg := ig.machinePidEncode()

	machineCodeLen := len(machineCode)
	if machineCode[machineCodeLen-6:machineCodeLen] != fmt.Sprintf("%x", machineCodeFromIg) {
		t.Error("Test MachineCode Error")
	}

	pidCodeLen := len(pidCode)
	if pidCode[pidCodeLen-4:pidCodeLen] != fmt.Sprintf("%x", pidCodeFromIg) {
		t.Error("Test PidCode Error")
	}

	t.Log("Test MachineCode PidCode PASS")
}
<commit_msg>add benchmark test<commit_after>package igener

import (
	"fmt"
	"hash/crc32"
	"os"
	"testing"
	"time"
)

func BenchmarkIGener(b *testing.B) {
	ig := NewIGener()
	for n := 0; n < b.N; n++ {
		<-ig
	}
}

func TestIGener(t *testing.T) {
	ig := NewIGener()
	var id string
	m := make(map[string]struct{})
	for i := 0; i < 10000; i++ {
		id = <-ig
		m[id] = struct{}{}
	}
	if len(m) != 10000 {
		t.Error("TestIGener Error")
	}
	t.Log("Test IGener PASS")
}

func TestMachinePidEncode(t *testing.T) {
	hostname, _ := os.Hostname()
	hashCode := crc32.ChecksumIEEE([]byte(hostname))
	machineCode := fmt.Sprintf("%06x", hashCode)
	pid := os.Getpid()
	pidCode := fmt.Sprintf("%04x", pid)

	ig := &IGener{
		second: time.Now().Unix(),
		inc:    0,
		idChan: make(chan string),
	}

	machineCodeFromIg, pidCodeFromIg := ig.machinePidEncode()

	machineCodeLen := len(machineCode)
	if machineCode[machineCodeLen-6:machineCodeLen] != fmt.Sprintf("%x", machineCodeFromIg) {
		t.Error("Test MachineCode Error")
	}

	pidCodeLen := len(pidCode)
	if pidCode[pidCodeLen-4:pidCodeLen] != fmt.Sprintf("%x", pidCodeFromIg) {
		t.Error("Test PidCode Error")
	}

	t.Log("Test MachineCode PidCode PASS")
}
<|endoftext|>


<commit_before>/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you 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 main

import (
	"errors"
	"fmt"
	"strconv"

	"github.com/hyperledger/fabric/core/chaincode/shim"
)

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

func (t *SimpleChaincode) Init(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) {
	var A, B string    // Entities
	var Aval, Bval int // Asset holdings
	var err error

	if len(args) == 0 {
		return nil, errors.New("Incorrect number of arguments. At least one Meter's name is required.")
	}

	if len(args) != 4 {
		return nil, errors.New("Incorrect number of arguments. Expecting 4")
	}

	// Initialize the chaincode
	A = args[0]
	Aval, err = strconv.Atoi(args[1])
	if err != nil {
		return nil, errors.New("Expecting integer value for asset holding")
	}
	B = args[2]
	Bval, err = strconv.Atoi(args[3])
	if err != nil {
		return nil, errors.New("Expecting integer value for asset holding")
	}
	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)

	// Write the state to the ledger
	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
	if err != nil {
		return nil, err
	}

	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
	if err != nil {
		return nil, err
	}

	return nil, nil
}

// Transaction makes payment of X units from A to B
func (t *SimpleChaincode) Invoke(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) {
	if function == "delete" {
		// Deletes an entity from its state
		return t.delete(stub, args)
	}

	var A, B string    // Entities
	var Aval, Bval int // Asset holdings
	var X int          // Transaction value
	var err error

	if len(args) != 3 {
		return nil, errors.New("Incorrect number of arguments. Expecting 3")
	}

	A = args[0]
	B = args[1]

	// Get the state from the ledger
	// TODO: will be nice to have a GetAllState call to ledger
	Avalbytes, err := stub.GetState(A)
	if err != nil {
		return nil, errors.New("Failed to get state")
	}
	if Avalbytes == nil {
		return nil, errors.New("Entity not found")
	}
	Aval, _ = strconv.Atoi(string(Avalbytes))

	Bvalbytes, err := stub.GetState(B)
	if err != nil {
		return nil, errors.New("Failed to get state")
	}
	if Bvalbytes == nil {
		return nil, errors.New("Entity not found")
	}
	Bval, _ = strconv.Atoi(string(Bvalbytes))

	// Perform the execution
	X, err = strconv.Atoi(args[2])
	Aval = Aval - X
	Bval = Bval + X
	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)

	// Write the state back to the ledger
	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
	if err != nil {
		return nil, err
	}

	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
	if err != nil {
		return nil, err
	}

	return nil, nil
}

// Deletes an entity from state
func (t *SimpleChaincode) delete(stub *shim.ChaincodeStub, args []string) ([]byte, error) {
	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting 1")
	}

	A := args[0]

	// Delete the key from the state in ledger
	err := stub.DelState(A)
	if err != nil {
		return nil, errors.New("Failed to delete state")
	}

	return nil, nil
}

// Query callback representing the query of a chaincode
func (t *SimpleChaincode) Query(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) {
	if function != "query" {
		return nil, errors.New("Invalid query function name. Expecting \"query\"")
	}
	var A string // Entities
	var err error

	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting name of the person to query")
	}

	A = args[0]

	// Get the state from the ledger
	Avalbytes, err := stub.GetState(A)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"
		return nil, errors.New(jsonResp)
	}

	if Avalbytes == nil {
		jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"
		return nil, errors.New(jsonResp)
	}

	jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}"
	fmt.Printf("Query Response:%s\n", jsonResp)
	return Avalbytes, nil
}

func main() {
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}
<commit_msg>create meter command added<commit_after>/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you 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 main

import (
	"errors"
	"fmt"
	"strconv"

	"github.com/hyperledger/fabric/core/chaincode/shim"
)

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

func (t *SimpleChaincode) Init(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) {
	var A, B string    // Entities
	var Aval, Bval int // Asset holdings
	var err error

	if len(args) == 0 {
		return nil, errors.New("Incorrect number of arguments. At least one Meter's name is required.")
	}
	for _,name := range args {
		if len(name) == 0{
			continue
		}
		err = stub.PutState(name, 0);
		if err != nil {
			return nil, errors.New("Meter cannot be created")
		}
	}

	if len(args) != 4 {
		return nil, errors.New("Incorrect number of arguments. Expecting 4")
	}

	// Initialize the chaincode
	A = args[0]
	Aval, err = strconv.Atoi(args[1])
	if err != nil {
		return nil, errors.New("Expecting integer value for asset holding")
	}
	B = args[2]
	Bval, err = strconv.Atoi(args[3])
	if err != nil {
		return nil, errors.New("Expecting integer value for asset holding")
	}
	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)

	// Write the state to the ledger
	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
	if err != nil {
		return nil, err
	}

	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
	if err != nil {
		return nil, err
	}

	return nil, nil
}

// Transaction makes payment of X units from A to B
func (t *SimpleChaincode) Invoke(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) {
	if function == "delete" {
		// Deletes an entity from its state
		return t.delete(stub, args)
	}

	var A, B string    // Entities
	var Aval, Bval int // Asset holdings
	var X int          // Transaction value
	var err error

	if len(args) != 3 {
		return nil, errors.New("Incorrect number of arguments. Expecting 3")
	}

	A = args[0]
	B = args[1]

	// Get the state from the ledger
	// TODO: will be nice to have a GetAllState call to ledger
	Avalbytes, err := stub.GetState(A)
	if err != nil {
		return nil, errors.New("Failed to get state")
	}
	if Avalbytes == nil {
		return nil, errors.New("Entity not found")
	}
	Aval, _ = strconv.Atoi(string(Avalbytes))

	Bvalbytes, err := stub.GetState(B)
	if err != nil {
		return nil, errors.New("Failed to get state")
	}
	if Bvalbytes == nil {
		return nil, errors.New("Entity not found")
	}
	Bval, _ = strconv.Atoi(string(Bvalbytes))

	// Perform the execution
	X, err = strconv.Atoi(args[2])
	Aval = Aval - X
	Bval = Bval + X
	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)

	// Write the state back to the ledger
	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
	if err != nil {
		return nil, err
	}

	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
	if err != nil {
		return nil, err
	}

	return nil, nil
}

// Deletes an entity from state
func (t *SimpleChaincode) delete(stub *shim.ChaincodeStub, args []string) ([]byte, error) {
	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting 1")
	}

	A := args[0]

	// Delete the key from the state in ledger
	err := stub.DelState(A)
	if err != nil {
		return nil, errors.New("Failed to delete state")
	}

	return nil, nil
}

// Query callback representing the query of a chaincode
func (t *SimpleChaincode) Query(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) {
	if function != "query" {
		return nil, errors.New("Invalid query function name. Expecting \"query\"")
	}
	var A string // Entities
	var err error

	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting name of the person to query")
	}

	A = args[0]

	// Get the state from the ledger
	Avalbytes, err := stub.GetState(A)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"
		return nil, errors.New(jsonResp)
	}

	if Avalbytes == nil {
		jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"
		return nil, errors.New(jsonResp)
	}

	jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}"
	fmt.Printf("Query Response:%s\n", jsonResp)
	return Avalbytes, nil
}

func main() {
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}
<|endoftext|>


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

package rand_test

import (
	"fmt"
	"math/rand"
	"os"
	"text/tabwriter"
)

// This test serves as an example but also makes sure we don't change
// the output of the random number generator when given a fixed seed.

// This example shows the use of each of the methods on a *Rand.
// The use of the global functions is the same, without the receiver.
func Example() {
	// Create and seed the generator.
	// Typically a non-fixed seed should be used, such as time.Now().UnixNano().
	// Using a fixed seed will produce the same output on every run.
	r := rand.New(rand.NewSource(99))

	// The tabwriter here helps us generate aligned output.
	w := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0)
	defer w.Flush()
	show := func(name string, v1, v2, v3 interface{}) {
		fmt.Fprintf(w, "%s\t%v\t%v\t%v\n", name, v1, v2, v3)
	}

	// Float32 and Float64 values are in [0, 1).
	show("Float32", r.Float32(), r.Float32(), r.Float32())
	show("Float64", r.Float64(), r.Float64(), r.Float64())

	// ExpFloat64 values have an average of 1 but decay exponentially.
	show("ExpFloat64", r.ExpFloat64(), r.ExpFloat64(), r.ExpFloat64())

	// NormFloat64 values have an average of 0 and a standard deviation of 1.
	show("NormFloat64", r.NormFloat64(), r.NormFloat64(), r.NormFloat64())

	// Int31, Int63, and Uint32 generate values of the given width.
	// The Int method (not shown) is like either Int31 or Int64
	// depending on the size of 'int'.
	show("Int31", r.Int31(), r.Int31(), r.Int31())
	show("Int63", r.Int63(), r.Int63(), r.Int63())
	show("Uint32", r.Int63(), r.Int63(), r.Int63())

	// Intn, Int31n, and Int63n limit their output to be < n.
	// They do so more carefully than using r.Int()%n.
	show("Intn(10)", r.Intn(10), r.Intn(10), r.Intn(10))
	show("Int31n(10)", r.Int31n(10), r.Int31n(10), r.Int31n(10))
	show("Int63n(10)", r.Int63n(10), r.Int63n(10), r.Int63n(10))

	// Perm generates a random permutation of the numbers [0, n).
	show("Perm", r.Perm(5), r.Perm(5), r.Perm(5))
	// Output:
	// Float32     0.2635776           0.6358173           0.6718283
	// Float64     0.628605430454327   0.4504798828572669  0.9562755949377957
	// ExpFloat64  0.3362240648200941  1.4256072328483647  0.24354758816173044
	// NormFloat64 0.17233959114940064 1.577014951434847   0.04259129641113857
	// Int31       1501292890          1486668269          182840835
	// Int63       3546343826724305832 5724354148158589552 5239846799706671610
	// Uint32      5927547564735367388 637072299495207830  4128311955958246186
	// Intn(10)    1                   2                   5
	// Int31n(10)  4                   7                   8
	// Int63n(10)  7                   6                   3
	// Perm        [1 4 2 3 0]         [4 2 1 3 0]         [1 2 4 0 3]
}
<commit_msg>math/rand: fix typo in example comment.<commit_after>// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package rand_test

import (
	"fmt"
	"math/rand"
	"os"
	"text/tabwriter"
)

// This test serves as an example but also makes sure we don't change
// the output of the random number generator when given a fixed seed.

// This example shows the use of each of the methods on a *Rand.
// The use of the global functions is the same, without the receiver.
func Example() {
	// Create and seed the generator.
	// Typically a non-fixed seed should be used, such as time.Now().UnixNano().
	// Using a fixed seed will produce the same output on every run.
	r := rand.New(rand.NewSource(99))

	// The tabwriter here helps us generate aligned output.
	w := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0)
	defer w.Flush()
	show := func(name string, v1, v2, v3 interface{}) {
		fmt.Fprintf(w, "%s\t%v\t%v\t%v\n", name, v1, v2, v3)
	}

	// Float32 and Float64 values are in [0, 1).
	show("Float32", r.Float32(), r.Float32(), r.Float32())
	show("Float64", r.Float64(), r.Float64(), r.Float64())

	// ExpFloat64 values have an average of 1 but decay exponentially.
	show("ExpFloat64", r.ExpFloat64(), r.ExpFloat64(), r.ExpFloat64())

	// NormFloat64 values have an average of 0 and a standard deviation of 1.
	show("NormFloat64", r.NormFloat64(), r.NormFloat64(), r.NormFloat64())

	// Int31, Int63, and Uint32 generate values of the given width.
	// The Int method (not shown) is like either Int31 or Int63
	// depending on the size of 'int'.
	show("Int31", r.Int31(), r.Int31(), r.Int31())
	show("Int63", r.Int63(), r.Int63(), r.Int63())
	show("Uint32", r.Int63(), r.Int63(), r.Int63())

	// Intn, Int31n, and Int63n limit their output to be < n.
	// They do so more carefully than using r.Int()%n.
	show("Intn(10)", r.Intn(10), r.Intn(10), r.Intn(10))
	show("Int31n(10)", r.Int31n(10), r.Int31n(10), r.Int31n(10))
	show("Int63n(10)", r.Int63n(10), r.Int63n(10), r.Int63n(10))

	// Perm generates a random permutation of the numbers [0, n).
	show("Perm", r.Perm(5), r.Perm(5), r.Perm(5))
	// Output:
	// Float32     0.2635776           0.6358173           0.6718283
	// Float64     0.628605430454327   0.4504798828572669  0.9562755949377957
	// ExpFloat64  0.3362240648200941  1.4256072328483647  0.24354758816173044
	// NormFloat64 0.17233959114940064 1.577014951434847   0.04259129641113857
	// Int31       1501292890          1486668269          182840835
	// Int63       3546343826724305832 5724354148158589552 5239846799706671610
	// Uint32      5927547564735367388 637072299495207830  4128311955958246186
	// Intn(10)    1                   2                   5
	// Int31n(10)  4                   7                   8
	// Int63n(10)  7                   6                   3
	// Perm        [1 4 2 3 0]         [4 2 1 3 0]         [1 2 4 0 3]
}
<|endoftext|>


<commit_before>package sql

import (
	"database/sql"
	"errors"
	"flag"
	"fmt"
	"github.com/golang/glog"
	_ "github.com/lib/pq"
	"sync"
)

var (
	maxOpenConns = flag.Int("sql_max_open_conn", 0, "Max number of open connections, 0 is no limit")
	maxIdleConns = flag.Int("sql_max_idle_conn", 10, "Max number of open connections")
)

func NewPostgres() *Postgres {
	return &Postgres{
		User:            "ubuntu",
		Db:              "circle_test",
		Ssl:             false,
		DoCreateSchemas: true,
		DoUpdateSchemas: false,
	}
}

type Postgres struct {
	Host            string
	Port            int
	Db              string
	User            string
	Password        string
	Schemas         []*Schema
	DoCreateSchemas bool
	DoUpdateSchemas bool

	Ssl  bool
	conn *sql.DB
}

var (
	initialize_system sync.Once
)

var (
	mutex1                    sync.Mutex
	sync_by_connection_string = make(map[string]sync.Once, 0)
	conn_by_connection_string = make(map[string]*sql.DB, 0)
)

func (this *Postgres) Conn() *sql.DB {
	return this.conn
}

func (this *Postgres) Open() error {

	conn_string := this.connection_string()

	glog.Infoln("Postgres connection string:", conn_string)

	mutex1.Lock()
	once, has := sync_by_connection_string[conn_string]
	if !has {
		once = sync.Once{}
		sync_by_connection_string[conn_string] = once
	}
	mutex1.Unlock()

	once.Do(func() {
		glog.Infoln("Connecting to db:", conn_string)
		db, err := sql.Open(string(POSTGRES), conn_string)
		if err != nil {
			panic(err)
		}
		db.SetMaxIdleConns(*maxIdleConns)
		db.SetMaxOpenConns(*maxOpenConns)
		conn_by_connection_string[conn_string] = db
		glog.Infoln("Connected to db:", conn_string, "caching the connection handle")
	})

	this.conn, has = conn_by_connection_string[conn_string]
	if !has {
		panic(errors.New("error-no-initialized-db-connections"))
	}

	glog.Infoln("Connected:", this.conn)
	initialize_system.Do(func() {
		// bootstrap the system schema
		err1 := postgres_schema.Initialize(this.conn)
		glog.Infoln("Initialized system schema:", err1)
		if err1 != nil {
			panic(err1)
		}
		err2 := postgres_schema.PrepareStatements(this.conn)
		glog.Infoln("Prepared statements:", err2)
		if err2 != nil {
			panic(err2)
		}
	})
	err := sync_schemas(this.conn, this.Schemas, this.DoCreateSchemas, this.DoUpdateSchemas)
	if err != nil {
		return err
	}
	// prepare statements
	for _, s := range this.Schemas {
		err = s.PrepareStatements(this.conn)
		if err != nil {
			return err
		}
	}
	return nil
}

func (this *Postgres) Insert(schema *Schema, insert StatementKey, args ...interface{}) error {
	return schema.Insert(this.conn, insert, args...)
}

func (this *Postgres) Upsert(schema *Schema, update, insert StatementKey, args ...interface{}) error {
	return schema.Upsert(this.conn, update, insert, args...)
}

func (this *Postgres) Delete(schema *Schema, delete StatementKey, args ...interface{}) error {
	return schema.Delete(this.conn, delete, args...)
}

func (this *Postgres) GetOne(schema *Schema, get StatementKey, opt *Options, args ...interface{}) error {
	return schema.GetOne(this.conn, get, opt, args...)
}

func (this *Postgres) GetAll(schema *Schema, get StatementKey, opt *Options, c Collect, args ...interface{}) error {
	return schema.GetAll(this.conn, get, opt, c, args...)
}

func (this *Postgres) Close() error {
	if this.conn == nil {
		return ErrNotConnected
	}
	return this.conn.Close()
}

func (this *Postgres) DropAll() error {
	// This just drops everything... dangerous!
	for _, s := range this.Schemas {
		err := s.DropTables(this.conn)
		if err != nil {
			return err
		}
	}
	return nil
}

func (this *Postgres) TruncateAll() error {
	for _, s := range this.Schemas {
		for t, _ := range s.CreateTables {
			glog.Infoln("Truncating", t)
			_, err := this.conn.Exec("delete from " + t + " where true")
			if err != nil {
				return err
			}
		}
	}
	return nil
}

func (this *Postgres) connection_string() string {
	cs := fmt.Sprintf("user=%s dbname=%s", this.User, this.Db)
	if this.Password != "" {
		cs += fmt.Sprintf(" password='%s'", this.Password)
	}
	if this.Host != "" {
		cs += fmt.Sprintf(" host=%s", this.Host)
	}
	if this.Port > 0 {
		cs += fmt.Sprintf(" port=%d", this.Port)
	}
	if this.Ssl {
		cs += " sslmode=verify-full"
	} else {
		cs += " sslmode=disable"
	}
	return cs
}

var postgres_schema = &Schema{
	Platform: POSTGRES,
	Name:     "system",
	Version:  1,
	CreateTables: map[string]string{
		"schema_versions": `
create table if not exists system_schema_versions (
    schema_name varchar,
    version     integer,
    repo_url    varchar,
    commit_hash varchar null
)
		`,
	},
	PreparedStatements: map[StatementKey]Statement{
		kSelectVersionInfoBySchemaName: Statement{
			Query: `
select version, commit_hash from system_schema_versions
where schema_name=$1
`},
		kDeleteVersionInfo: Statement{
			Query: `
delete from system_schema_versions where schema_name=$1
`,
			Args: func(args ...interface{}) ([]interface{}, error) {
				if len(args) != 1 {
					return nil, errors.New("args-mismatch")
				}
				schema_name, ok := args[0].(string)
				if !ok {
					return nil, errors.New("bad-schema-name")
				}
				return []interface{}{
					schema_name,
				}, nil
			},
		},
		kInsertVersionInfo: Statement{
			Query: `
insert into system_schema_versions (schema_name, version, repo_url, commit_hash)
values ($1, $2, $3, $4)
`,
			Args: func(args ...interface{}) ([]interface{}, error) {
				if len(args) != 4 {
					return nil, errors.New("args-mismatch")
				}
				schema_name, ok := args[0].(string)
				if !ok {
					return nil, errors.New("bad-schema-name")
				}
				version, ok := args[1].(int)
				if !ok {
					return nil, errors.New("bad-version")
				}
				repo, ok := args[2].(string)
				if !ok {
					return nil, errors.New("bad-repo")
				}
				commit_hash, ok := args[3].(string)
				if !ok {
					return nil, errors.New("bad-commit-hash")
				}
				return []interface{}{
					schema_name,
					version,
					repo,
					commit_hash,
				}, nil
			},
		},
		kUpdateVersionInfo: Statement{
			Query: `
update system_schema_versions
set version=$1, repo_url=$2, commit_hash=$3
where schema_name=$4
`,
			Args: func(args ...interface{}) ([]interface{}, error) {
				if len(args) != 4 {
					return nil, errors.New("args-mismatch")
				}
				schema_name, ok := args[0].(string)
				if !ok {
					return nil, errors.New("bad-schema-name")
				}
				version, ok := args[1].(int)
				if !ok {
					return nil, errors.New("bad-version")
				}
				repo, ok := args[2].(string)
				if !ok {
					return nil, errors.New("bad-repo")
				}
				commit_hash, ok := args[3].(string)
				if !ok {
					return nil, errors.New("bad-commit-hash")
				}
				return []interface{}{
					version,
					repo,
					commit_hash,
					schema_name,
				}, nil
			},
		},
	},
}
<commit_msg>Make sure once sync really executes only once<commit_after>package sql

import (
	"database/sql"
	"errors"
	"flag"
	"fmt"
	"github.com/golang/glog"
	_ "github.com/lib/pq"
	"sync"
)

var (
	maxOpenConns = flag.Int("sql_max_open_conn", 0, "Max number of open connections, 0 is no limit")
	maxIdleConns = flag.Int("sql_max_idle_conn", 10, "Max number of open connections")
)

func NewPostgres() *Postgres {
	return &Postgres{
		User:            "ubuntu",
		Db:              "circle_test",
		Ssl:             false,
		DoCreateSchemas: true,
		DoUpdateSchemas: false,
	}
}

type Postgres struct {
	Host            string
	Port            int
	Db              string
	User            string
	Password        string
	Schemas         []*Schema
	DoCreateSchemas bool
	DoUpdateSchemas bool

	Ssl  bool
	conn *sql.DB
}

var (
	initialize_system sync.Once
)

var (
	mutex1                    sync.Mutex
	sync_by_connection_string = make(map[string]*sync.Once, 0)
	conn_by_connection_string = make(map[string]*sql.DB, 0)
)

func (this *Postgres) Conn() *sql.DB {
	return this.conn
}

func (this *Postgres) Open() error {

	conn_string := this.connection_string()

	glog.Infoln("Postgres connection string:", conn_string)

	mutex1.Lock()
	once, has := sync_by_connection_string[conn_string]
	if !has {
		once = &sync.Once{}
		sync_by_connection_string[conn_string] = once
	}
	mutex1.Unlock()

	once.Do(func() {
		glog.Infoln("Connecting to db:", conn_string)
		db, err := sql.Open(string(POSTGRES), conn_string)
		if err != nil {
			panic(err)
		}
		db.SetMaxIdleConns(*maxIdleConns)
		db.SetMaxOpenConns(*maxOpenConns)
		conn_by_connection_string[conn_string] = db
		glog.Infoln("Connected to db:", conn_string, "caching the connection handle")
	})

	this.conn, has = conn_by_connection_string[conn_string]
	if !has {
		panic(errors.New("error-no-initialized-db-connections"))
	}

	if this.conn == nil {
		panic(errors.New("error-db-connection-is-nil"))
	}
	glog.Infoln("Connected (PING):", this.conn.Ping())
	initialize_system.Do(func() {
		// bootstrap the system schema
		err1 := postgres_schema.Initialize(this.conn)
		glog.Infoln("Initialized system schema:", err1)
		if err1 != nil {
			panic(err1)
		}
		err2 := postgres_schema.PrepareStatements(this.conn)
		glog.Infoln("Prepared statements:", err2)
		if err2 != nil {
			panic(err2)
		}
	})
	err := sync_schemas(this.conn, this.Schemas, this.DoCreateSchemas, this.DoUpdateSchemas)
	if err != nil {
		return err
	}
	// prepare statements
	for _, s := range this.Schemas {
		err = s.PrepareStatements(this.conn)
		if err != nil {
			return err
		}
	}
	return nil
}

func (this *Postgres) Insert(schema *Schema, insert StatementKey, args ...interface{}) error {
	return schema.Insert(this.conn, insert, args...)
}

func (this *Postgres) Upsert(schema *Schema, update, insert StatementKey, args ...interface{}) error {
	return schema.Upsert(this.conn, update, insert, args...)
}

func (this *Postgres) Delete(schema *Schema, delete StatementKey, args ...interface{}) error {
	return schema.Delete(this.conn, delete, args...)
}

func (this *Postgres) GetOne(schema *Schema, get StatementKey, opt *Options, args ...interface{}) error {
	return schema.GetOne(this.conn, get, opt, args...)
}

func (this *Postgres) GetAll(schema *Schema, get StatementKey, opt *Options, c Collect, args ...interface{}) error {
	return schema.GetAll(this.conn, get, opt, c, args...)
}

func (this *Postgres) Close() error {
	if this.conn == nil {
		return ErrNotConnected
	}
	return this.conn.Close()
}

func (this *Postgres) DropAll() error {
	// This just drops everything... dangerous!
	for _, s := range this.Schemas {
		err := s.DropTables(this.conn)
		if err != nil {
			return err
		}
	}
	return nil
}

func (this *Postgres) TruncateAll() error {
	for _, s := range this.Schemas {
		for t, _ := range s.CreateTables {
			glog.Infoln("Truncating", t)
			_, err := this.conn.Exec("delete from " + t + " where true")
			if err != nil {
				return err
			}
		}
	}
	return nil
}

func (this *Postgres) connection_string() string {
	cs := fmt.Sprintf("user=%s dbname=%s", this.User, this.Db)
	if this.Password != "" {
		cs += fmt.Sprintf(" password='%s'", this.Password)
	}
	if this.Host != "" {
		cs += fmt.Sprintf(" host=%s", this.Host)
	}
	if this.Port > 0 {
		cs += fmt.Sprintf(" port=%d", this.Port)
	}
	if this.Ssl {
		cs += " sslmode=verify-full"
	} else {
		cs += " sslmode=disable"
	}
	return cs
}

var postgres_schema = &Schema{
	Platform: POSTGRES,
	Name:     "system",
	Version:  1,
	CreateTables: map[string]string{
		"schema_versions": `
create table if not exists system_schema_versions (
    schema_name varchar,
    version     integer,
    repo_url    varchar,
    commit_hash varchar null
)
		`,
	},
	PreparedStatements: map[StatementKey]Statement{
		kSelectVersionInfoBySchemaName: Statement{
			Query: `
select version, commit_hash from system_schema_versions
where schema_name=$1
`},
		kDeleteVersionInfo: Statement{
			Query: `
delete from system_schema_versions where schema_name=$1
`,
			Args: func(args ...interface{}) ([]interface{}, error) {
				if len(args) != 1 {
					return nil, errors.New("args-mismatch")
				}
				schema_name, ok := args[0].(string)
				if !ok {
					return nil, errors.New("bad-schema-name")
				}
				return []interface{}{
					schema_name,
				}, nil
			},
		},
		kInsertVersionInfo: Statement{
			Query: `
insert into system_schema_versions (schema_name, version, repo_url, commit_hash)
values ($1, $2, $3, $4)
`,
			Args: func(args ...interface{}) ([]interface{}, error) {
				if len(args) != 4 {
					return nil, errors.New("args-mismatch")
				}
				schema_name, ok := args[0].(string)
				if !ok {
					return nil, errors.New("bad-schema-name")
				}
				version, ok := args[1].(int)
				if !ok {
					return nil, errors.New("bad-version")
				}
				repo, ok := args[2].(string)
				if !ok {
					return nil, errors.New("bad-repo")
				}
				commit_hash, ok := args[3].(string)
				if !ok {
					return nil, errors.New("bad-commit-hash")
				}
				return []interface{}{
					schema_name,
					version,
					repo,
					commit_hash,
				}, nil
			},
		},
		kUpdateVersionInfo: Statement{
			Query: `
update system_schema_versions
set version=$1, repo_url=$2, commit_hash=$3
where schema_name=$4
`,
			Args: func(args ...interface{}) ([]interface{}, error) {
				if len(args) != 4 {
					return nil, errors.New("args-mismatch")
				}
				schema_name, ok := args[0].(string)
				if !ok {
					return nil, errors.New("bad-schema-name")
				}
				version, ok := args[1].(int)
				if !ok {
					return nil, errors.New("bad-version")
				}
				repo, ok := args[2].(string)
				if !ok {
					return nil, errors.New("bad-repo")
				}
				commit_hash, ok := args[3].(string)
				if !ok {
					return nil, errors.New("bad-commit-hash")
				}
				return []interface{}{
					version,
					repo,
					commit_hash,
					schema_name,
				}, nil
			},
		},
	},
}
<|endoftext|>


<commit_before>package sql

import (
	"database/sql"
	"errors"
	"flag"
	"fmt"
	"github.com/golang/glog"
	_ "github.com/lib/pq"
	"sync"
)

var (
	maxOpenConns = flag.Int("sql_max_open_conn", 0, "Max number of open connections, 0 is no limit")
	maxIdleConns = flag.Int("sql_max_idle_conn", 10, "Max number of open connections")
)

func NewPostgres() *Postgres {
	return &Postgres{
		User:            "ubuntu",
		Db:              "circle_test",
		Ssl:             false,
		DoCreateSchemas: true,
		DoUpdateSchemas: false,
	}
}

type Postgres struct {
	Host            string
	Port            int
	Db              string
	User            string
	Password        string
	Schemas         []*Schema
	DoCreateSchemas bool
	DoUpdateSchemas bool

	Ssl  bool
	conn *sql.DB
}

var (
	initialize_system sync.Once
)

var (
	mutex1                    sync.Mutex
	sync_by_connection_string = make(map[string]sync.Once, 0)
	conn_by_connection_string = make(map[string]*sql.DB, 0)
)

func (this *Postgres) Conn() *sql.DB {
	return this.conn
}

func (this *Postgres) Open() error {

	conn_string := this.connection_string()

	glog.Infoln("Postgres connection string:", conn_string)

	mutex1.Lock()
	once, has := sync_by_connection_string[conn_string]
	if !has {
		once = sync.Once{}
		sync_by_connection_string[conn_string] = once
	}
	mutex1.Unlock()

	once.Do(func() {
		db, err := sql.Open(string(POSTGRES), conn_string)
		if err != nil {
			panic(err)
		}
		db.SetMaxIdleConns(*maxIdleConns)
		db.SetMaxOpenConns(*maxOpenConns)
		conn_by_connection_string[conn_string] = db
	})

	this.conn, has = conn_by_connection_string[conn_string]
	if !has {
		panic(errors.New("error-no-initialized-db-connections"))
	}

	glog.Infoln("Connected:", this.conn)
	initialize_system.Do(func() {
		// bootstrap the system schema
		err1 := postgres_schema.Initialize(this.conn)
		glog.Infoln("Initialized system schema:", err1)
		if err1 != nil {
			panic(err1)
		}
		err2 := postgres_schema.PrepareStatements(this.conn)
		glog.Infoln("Prepared statements:", err2)
		if err2 != nil {
			panic(err2)
		}
	})
	err := sync_schemas(this.conn, this.Schemas, this.DoCreateSchemas, this.DoUpdateSchemas)
	if err != nil {
		return err
	}
	// prepare statements
	for _, s := range this.Schemas {
		err = s.PrepareStatements(this.conn)
		if err != nil {
			return err
		}
	}
	return nil
}

func (this *Postgres) Insert(schema *Schema, insert StatementKey, args ...interface{}) error {
	return schema.Insert(this.conn, insert, args...)
}

func (this *Postgres) Upsert(schema *Schema, update, insert StatementKey, args ...interface{}) error {
	return schema.Upsert(this.conn, update, insert, args...)
}

func (this *Postgres) Delete(schema *Schema, delete StatementKey, args ...interface{}) error {
	return schema.Delete(this.conn, delete, args...)
}

func (this *Postgres) GetOne(schema *Schema, get StatementKey, opt *Options, args ...interface{}) error {
	return schema.GetOne(this.conn, get, opt, args...)
}

func (this *Postgres) GetAll(schema *Schema, get StatementKey, opt *Options, c Collect, args ...interface{}) error {
	return schema.GetAll(this.conn, get, opt, c, args...)
}

func (this *Postgres) Close() error {
	if this.conn == nil {
		return ErrNotConnected
	}
	return this.conn.Close()
}

func (this *Postgres) DropAll() error {
	// This just drops everything... dangerous!
	for _, s := range this.Schemas {
		err := s.DropTables(this.conn)
		if err != nil {
			return err
		}
	}
	return nil
}

func (this *Postgres) TruncateAll() error {
	for _, s := range this.Schemas {
		for t, _ := range s.CreateTables {
			glog.Infoln("Truncating", t)
			_, err := this.conn.Exec("delete from " + t + " where true")
			if err != nil {
				return err
			}
		}
	}
	return nil
}

func (this *Postgres) connection_string() string {
	cs := fmt.Sprintf("user=%s dbname=%s", this.User, this.Db)
	if this.Password != "" {
		cs += fmt.Sprintf(" password='%s'", this.Password)
	}
	if this.Host != "" {
		cs += fmt.Sprintf(" host=%s", this.Host)
	}
	if this.Port > 0 {
		cs += fmt.Sprintf(" port=%d", this.Port)
	}
	if this.Ssl {
		cs += " sslmode=verify-full"
	} else {
		cs += " sslmode=disable"
	}
	return cs
}

var postgres_schema = &Schema{
	Platform: POSTGRES,
	Name:     "system",
	Version:  1,
	CreateTables: map[string]string{
		"schema_versions": `
create table if not exists system_schema_versions (
    schema_name varchar,
    version     integer,
    repo_url    varchar,
    commit_hash varchar null
)
		`,
	},
	PreparedStatements: map[StatementKey]Statement{
		kSelectVersionInfoBySchemaName: Statement{
			Query: `
select version, commit_hash from system_schema_versions
where schema_name=$1
`},
		kDeleteVersionInfo: Statement{
			Query: `
delete from system_schema_versions where schema_name=$1
`,
			Args: func(args ...interface{}) ([]interface{}, error) {
				if len(args) != 1 {
					return nil, errors.New("args-mismatch")
				}
				schema_name, ok := args[0].(string)
				if !ok {
					return nil, errors.New("bad-schema-name")
				}
				return []interface{}{
					schema_name,
				}, nil
			},
		},
		kInsertVersionInfo: Statement{
			Query: `
insert into system_schema_versions (schema_name, version, repo_url, commit_hash)
values ($1, $2, $3, $4)
`,
			Args: func(args ...interface{}) ([]interface{}, error) {
				if len(args) != 4 {
					return nil, errors.New("args-mismatch")
				}
				schema_name, ok := args[0].(string)
				if !ok {
					return nil, errors.New("bad-schema-name")
				}
				version, ok := args[1].(int)
				if !ok {
					return nil, errors.New("bad-version")
				}
				repo, ok := args[2].(string)
				if !ok {
					return nil, errors.New("bad-repo")
				}
				commit_hash, ok := args[3].(string)
				if !ok {
					return nil, errors.New("bad-commit-hash")
				}
				return []interface{}{
					schema_name,
					version,
					repo,
					commit_hash,
				}, nil
			},
		},
		kUpdateVersionInfo: Statement{
			Query: `
update system_schema_versions
set version=$1, repo_url=$2, commit_hash=$3
where schema_name=$4
`,
			Args: func(args ...interface{}) ([]interface{}, error) {
				if len(args) != 4 {
					return nil, errors.New("args-mismatch")
				}
				schema_name, ok := args[0].(string)
				if !ok {
					return nil, errors.New("bad-schema-name")
				}
				version, ok := args[1].(int)
				if !ok {
					return nil, errors.New("bad-version")
				}
				repo, ok := args[2].(string)
				if !ok {
					return nil, errors.New("bad-repo")
				}
				commit_hash, ok := args[3].(string)
				if !ok {
					return nil, errors.New("bad-commit-hash")
				}
				return []interface{}{
					version,
					repo,
					commit_hash,
					schema_name,
				}, nil
			},
		},
	},
}
<commit_msg>Minor logging<commit_after>package sql

import (
	"database/sql"
	"errors"
	"flag"
	"fmt"
	"github.com/golang/glog"
	_ "github.com/lib/pq"
	"sync"
)

var (
	maxOpenConns = flag.Int("sql_max_open_conn", 0, "Max number of open connections, 0 is no limit")
	maxIdleConns = flag.Int("sql_max_idle_conn", 10, "Max number of open connections")
)

func NewPostgres() *Postgres {
	return &Postgres{
		User:            "ubuntu",
		Db:              "circle_test",
		Ssl:             false,
		DoCreateSchemas: true,
		DoUpdateSchemas: false,
	}
}

type Postgres struct {
	Host            string
	Port            int
	Db              string
	User            string
	Password        string
	Schemas         []*Schema
	DoCreateSchemas bool
	DoUpdateSchemas bool

	Ssl  bool
	conn *sql.DB
}

var (
	initialize_system sync.Once
)

var (
	mutex1                    sync.Mutex
	sync_by_connection_string = make(map[string]sync.Once, 0)
	conn_by_connection_string = make(map[string]*sql.DB, 0)
)

func (this *Postgres) Conn() *sql.DB {
	return this.conn
}

func (this *Postgres) Open() error {

	conn_string := this.connection_string()

	glog.Infoln("Postgres connection string:", conn_string)

	mutex1.Lock()
	once, has := sync_by_connection_string[conn_string]
	if !has {
		once = sync.Once{}
		sync_by_connection_string[conn_string] = once
	}
	mutex1.Unlock()

	once.Do(func() {
		glog.Infoln("Connecting to db:", conn_string)
		db, err := sql.Open(string(POSTGRES), conn_string)
		if err != nil {
			panic(err)
		}
		db.SetMaxIdleConns(*maxIdleConns)
		db.SetMaxOpenConns(*maxOpenConns)
		conn_by_connection_string[conn_string] = db
		glog.Infoln("Connected to db:", conn_string, "caching the connection handle")
	})

	this.conn, has = conn_by_connection_string[conn_string]
	if !has {
		panic(errors.New("error-no-initialized-db-connections"))
	}

	glog.Infoln("Connected:", this.conn)
	initialize_system.Do(func() {
		// bootstrap the system schema
		err1 := postgres_schema.Initialize(this.conn)
		glog.Infoln("Initialized system schema:", err1)
		if err1 != nil {
			panic(err1)
		}
		err2 := postgres_schema.PrepareStatements(this.conn)
		glog.Infoln("Prepared statements:", err2)
		if err2 != nil {
			panic(err2)
		}
	})
	err := sync_schemas(this.conn, this.Schemas, this.DoCreateSchemas, this.DoUpdateSchemas)
	if err != nil {
		return err
	}
	// prepare statements
	for _, s := range this.Schemas {
		err = s.PrepareStatements(this.conn)
		if err != nil {
			return err
		}
	}
	return nil
}

func (this *Postgres) Insert(schema *Schema, insert StatementKey, args ...interface{}) error {
	return schema.Insert(this.conn, insert, args...)
}

func (this *Postgres) Upsert(schema *Schema, update, insert StatementKey, args ...interface{}) error {
	return schema.Upsert(this.conn, update, insert, args...)
}

func (this *Postgres) Delete(schema *Schema, delete StatementKey, args ...interface{}) error {
	return schema.Delete(this.conn, delete, args...)
}

func (this *Postgres) GetOne(schema *Schema, get StatementKey, opt *Options, args ...interface{}) error {
	return schema.GetOne(this.conn, get, opt, args...)
}

func (this *Postgres) GetAll(schema *Schema, get StatementKey, opt *Options, c Collect, args ...interface{}) error {
	return schema.GetAll(this.conn, get, opt, c, args...)
}

func (this *Postgres) Close() error {
	if this.conn == nil {
		return ErrNotConnected
	}
	return this.conn.Close()
}

func (this *Postgres) DropAll() error {
	// This just drops everything... dangerous!
	for _, s := range this.Schemas {
		err := s.DropTables(this.conn)
		if err != nil {
			return err
		}
	}
	return nil
}

func (this *Postgres) TruncateAll() error {
	for _, s := range this.Schemas {
		for t, _ := range s.CreateTables {
			glog.Infoln("Truncating", t)
			_, err := this.conn.Exec("delete from " + t + " where true")
			if err != nil {
				return err
			}
		}
	}
	return nil
}

func (this *Postgres) connection_string() string {
	cs := fmt.Sprintf("user=%s dbname=%s", this.User, this.Db)
	if this.Password != "" {
		cs += fmt.Sprintf(" password='%s'", this.Password)
	}
	if this.Host != "" {
		cs += fmt.Sprintf(" host=%s", this.Host)
	}
	if this.Port > 0 {
		cs += fmt.Sprintf(" port=%d", this.Port)
	}
	if this.Ssl {
		cs += " sslmode=verify-full"
	} else {
		cs += " sslmode=disable"
	}
	return cs
}

var postgres_schema = &Schema{
	Platform: POSTGRES,
	Name:     "system",
	Version:  1,
	CreateTables: map[string]string{
		"schema_versions": `
create table if not exists system_schema_versions (
    schema_name varchar,
    version     integer,
    repo_url    varchar,
    commit_hash varchar null
)
		`,
	},
	PreparedStatements: map[StatementKey]Statement{
		kSelectVersionInfoBySchemaName: Statement{
			Query: `
select version, commit_hash from system_schema_versions
where schema_name=$1
`},
		kDeleteVersionInfo: Statement{
			Query: `
delete from system_schema_versions where schema_name=$1
`,
			Args: func(args ...interface{}) ([]interface{}, error) {
				if len(args) != 1 {
					return nil, errors.New("args-mismatch")
				}
				schema_name, ok := args[0].(string)
				if !ok {
					return nil, errors.New("bad-schema-name")
				}
				return []interface{}{
					schema_name,
				}, nil
			},
		},
		kInsertVersionInfo: Statement{
			Query: `
insert into system_schema_versions (schema_name, version, repo_url, commit_hash)
values ($1, $2, $3, $4)
`,
			Args: func(args ...interface{}) ([]interface{}, error) {
				if len(args) != 4 {
					return nil, errors.New("args-mismatch")
				}
				schema_name, ok := args[0].(string)
				if !ok {
					return nil, errors.New("bad-schema-name")
				}
				version, ok := args[1].(int)
				if !ok {
					return nil, errors.New("bad-version")
				}
				repo, ok := args[2].(string)
				if !ok {
					return nil, errors.New("bad-repo")
				}
				commit_hash, ok := args[3].(string)
				if !ok {
					return nil, errors.New("bad-commit-hash")
				}
				return []interface{}{
					schema_name,
					version,
					repo,
					commit_hash,
				}, nil
			},
		},
		kUpdateVersionInfo: Statement{
			Query: `
update system_schema_versions
set version=$1, repo_url=$2, commit_hash=$3
where schema_name=$4
`,
			Args: func(args ...interface{}) ([]interface{}, error) {
				if len(args) != 4 {
					return nil, errors.New("args-mismatch")
				}
				schema_name, ok := args[0].(string)
				if !ok {
					return nil, errors.New("bad-schema-name")
				}
				version, ok := args[1].(int)
				if !ok {
					return nil, errors.New("bad-version")
				}
				repo, ok := args[2].(string)
				if !ok {
					return nil, errors.New("bad-repo")
				}
				commit_hash, ok := args[3].(string)
				if !ok {
					return nil, errors.New("bad-commit-hash")
				}
				return []interface{}{
					version,
					repo,
					commit_hash,
					schema_name,
				}, nil
			},
		},
	},
}
<|endoftext|>


<commit_before>package kember

import (
	"io"
	"fmt"
	"strings"
	"crypto/md5"
	"encoding/hex"
)

type Searcher struct {
	Log chan string
	Start string
	Iterations int64
	I int64
	Curr string
}

func Valid(hash string) bool {
	if len(hash) != 32 {
		return false
	}
	for _, runeValue := range strings.ToLower(hash) {
		if ((runeValue < 'a' || runeValue > 'f') && (runeValue < '0' || runeValue > '9')) {
	        return false
	    }
	}
	return true
}

func Search(gs *Searcher) {
	gs.Log <- fmt.Sprintf("search(%v, %v)!", gs.Curr, gs.Iterations)
	gs.I = int64(0)
	runes := []rune(gs.Curr)
	h := md5.New()
	for ; gs.Iterations < 0 || gs.I < gs.Iterations; gs.I++ {
		if gs.I % 10000000 == 0 {
			gs.Log <- gs.Curr
		}
		h.Reset()
		io.WriteString(h, gs.Curr)
		sum := h.Sum(nil)
		hash := hex.EncodeToString(sum[0:16])
		if gs.Curr == hash {
			gs.Log <- fmt.Sprintf("%v == %v <-- MATCH!!!", gs.Curr, hash)
		}
		increment(runes)
		gs.Curr = string(runes)
	}
	gs.Log <- "finished"
}

func increment(runes []rune) {
	runeCount := len(runes)
	pos := runeCount - 1
	for ; pos > 0 && runes[pos] == 'f'; pos-- {}
	for i := pos; i < runeCount; i++ {
		runes[i] = next(runes[i])
	}
}

func next(curr rune) rune {
	if curr == '9' {
		return 'a'
	} else if curr == 'f' {
		return '0'
	} else {
		return curr + 1
	}
}
<commit_msg>removed log of the 'search(..)' message<commit_after>package kember

import (
	"io"
	"fmt"
	"strings"
	"crypto/md5"
	"encoding/hex"
)

type Searcher struct {
	Log chan string
	Start string
	Iterations int64
	I int64
	Curr string
}

func Valid(hash string) bool {
	if len(hash) != 32 {
		return false
	}
	for _, runeValue := range strings.ToLower(hash) {
		if ((runeValue < 'a' || runeValue > 'f') && (runeValue < '0' || runeValue > '9')) {
	        return false
	    }
	}
	return true
}

func Search(gs *Searcher) {
	gs.I = int64(0)
	runes := []rune(gs.Curr)
	h := md5.New()
	for ; gs.Iterations < 0 || gs.I < gs.Iterations; gs.I++ {
		if gs.I % 10000000 == 0 {
			gs.Log <- gs.Curr
		}
		h.Reset()
		io.WriteString(h, gs.Curr)
		sum := h.Sum(nil)
		hash := hex.EncodeToString(sum[0:16])
		if gs.Curr == hash {
			gs.Log <- fmt.Sprintf("%v == %v <-- MATCH!!!", gs.Curr, hash)
		}
		increment(runes)
		gs.Curr = string(runes)
	}
	gs.Log <- "finished"
}

func increment(runes []rune) {
	runeCount := len(runes)
	pos := runeCount - 1
	for ; pos > 0 && runes[pos] == 'f'; pos-- {}
	for i := pos; i < runeCount; i++ {
		runes[i] = next(runes[i])
	}
}

func next(curr rune) rune {
	if curr == '9' {
		return 'a'
	} else if curr == 'f' {
		return '0'
	} else {
		return curr + 1
	}
}
<|endoftext|>