<commit_before>package carve

import (
	"image"
	"math"

	"github.com/disintegration/gift"
)

// ReduceHeight uses seam carving to reduce height of given image by n pixels.
func ReduceHeight(im image.Image, n int) image.Image {
	for x := 0; x < n; x++ {
		energy := GenerateEnergyMap(im)
		seam := GenerateSeam(energy)
		im = RemoveSeam(im, seam)
	}
	return im
}

// GenerateEnergyMap applies grayscale and sobel filters to the
// input image to create an energy map.
func GenerateEnergyMap(im image.Image) image.Image {
	g := gift.New(gift.Grayscale(), gift.Sobel())
	res := image.NewRGBA(im.Bounds())
	g.Draw(res, im)
	return res
}

// GenerateSeam returns the optimal horizontal seam for removal.
func GenerateSeam(im image.Image) Seam {
	mat := GenerateCostMatrix(im)
	return FindLowestCostSeam(mat)
}

// RemoveSeam creates a copy of the provided image, with the pixels at
// the points in the provided seam removed.
func RemoveSeam(im image.Image, seam Seam) image.Image {
	b := im.Bounds()
	out := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy()-1))
	min, max := b.Min, b.Max

	for _, point := range seam {
		x := point.X

		for y := min.Y; y < max.Y; y++ {
			if y == point.Y {
				continue
			}

			if y > point.Y {
				out.Set(x, y-1, im.At(x, y))
			} else {
				out.Set(x, y, im.At(x, y))
			}
		}
	}

	return out
}

type Seam []Point

type Point struct {
	X, Y int
}

// GenerateCostMatrix creates a matrix indicating the cumulative energy of the
// lowest cost seam from the left of the image to each pixel.
//
// mat[x][y] is the cumulative energy of the seam that runs from the left of
// the image to the pixel at column x, row y.
func GenerateCostMatrix(im image.Image) [][]float64 {
	min, max := im.Bounds().Min, im.Bounds().Max
	height, width := max.Y-min.Y, max.X-min.X

	mat := make([][]float64, width)
	for x := min.X; x < max.X; x++ {
		mat[x-min.X] = make([]float64, height)
	}

	for y := min.Y; y < max.Y; y++ {
		e, _, _, a := im.At(0, y).RGBA()
		mat[0][y-min.Y] = float64(e) / float64(a)
	}

	updatePoint := func(x, y int) {
		e, _, _, a := im.At(x, y).RGBA()

		up, down := math.MaxFloat64, math.MaxFloat64
		left := mat[x-1][y]
		if y != min.Y {
			up = mat[x-1][y-1]
		}
		if y < max.Y-1 {
			down = mat[x-1][y+1]
		}
		val := math.Min(float64(left), math.Min(float64(up), float64(down)))
		mat[x][y] = val + (float64(e) / float64(a))
	}

	// Calculate the remaining columns iteratively
	for x := min.X + 1; x < max.X; x++ {
		for y := min.Y; y < max.Y; y++ {
			updatePoint(x, y)
		}
	}

	return mat
}

// FindLowestCostSeam uses a cumulative cost matrix to identify the seam with
// the lowest total cumulative energy.
func FindLowestCostSeam(mat [][]float64) Seam {
	width, height := len(mat), len(mat[0])
	seam := make([]Point, width)

	min, y := math.MaxFloat64, 0
	for ind, val := range mat[width-1] {
		if val < min {
			min = val
			y = ind
		}
	}

	seam[width-1] = Point{X: width - 1, Y: y}
	for x := width - 2; x >= 0; x-- {
		left := mat[x][y]
		up, down := math.MaxFloat64, math.MaxFloat64
		if y != 0 {
			up = mat[x][y-1]
		}
		if y != height-1 {
			down = mat[x][y+1]
		}

		if up < left && up < down {
			seam[x] = Point{X: x, Y: y - 1}
			y = y - 1
		} else if left < up && left < down {
			seam[x] = Point{X: x, Y: y}
			y = y
		} else {
			seam[x] = Point{X: x, Y: y + 1}
			y = y + 1
		}
	}

	return seam
}
<commit_msg>Fix some linter issues<commit_after>// carve implements the seam carving algorithm for dyanmic image resizing.
package carve

import (
	"image"
	"math"

	"github.com/disintegration/gift"
)

// ReduceHeight uses seam carving to reduce height of given image by n pixels.
func ReduceHeight(im image.Image, n int) image.Image {
	for x := 0; x < n; x++ {
		energy := GenerateEnergyMap(im)
		seam := GenerateSeam(energy)
		im = RemoveSeam(im, seam)
	}
	return im
}

// GenerateEnergyMap applies grayscale and sobel filters to the
// input image to create an energy map.
func GenerateEnergyMap(im image.Image) image.Image {
	g := gift.New(gift.Grayscale(), gift.Sobel())
	res := image.NewRGBA(im.Bounds())
	g.Draw(res, im)
	return res
}

// GenerateSeam returns the optimal horizontal seam for removal.
func GenerateSeam(im image.Image) Seam {
	mat := GenerateCostMatrix(im)
	return FindLowestCostSeam(mat)
}

// RemoveSeam creates a copy of the provided image, with the pixels at
// the points in the provided seam removed.
func RemoveSeam(im image.Image, seam Seam) image.Image {
	b := im.Bounds()
	out := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy()-1))
	min, max := b.Min, b.Max

	for _, point := range seam {
		x := point.X

		for y := min.Y; y < max.Y; y++ {
			if y == point.Y {
				continue
			}

			if y > point.Y {
				out.Set(x, y-1, im.At(x, y))
			} else {
				out.Set(x, y, im.At(x, y))
			}
		}
	}

	return out
}

// Seam defines a sequence of pixels through an image to be removed.
type Seam []Point

// Point defines an X Y point in an image.
type Point struct {
	X, Y int
}

// GenerateCostMatrix creates a matrix indicating the cumulative energy of the
// lowest cost seam from the left of the image to each pixel.
//
// mat[x][y] is the cumulative energy of the seam that runs from the left of
// the image to the pixel at column x, row y.
func GenerateCostMatrix(im image.Image) [][]float64 {
	min, max := im.Bounds().Min, im.Bounds().Max
	height, width := max.Y-min.Y, max.X-min.X

	mat := make([][]float64, width)
	for x := min.X; x < max.X; x++ {
		mat[x-min.X] = make([]float64, height)
	}

	for y := min.Y; y < max.Y; y++ {
		e, _, _, a := im.At(0, y).RGBA()
		mat[0][y-min.Y] = float64(e) / float64(a)
	}

	updatePoint := func(x, y int) {
		e, _, _, a := im.At(x, y).RGBA()

		up, down := math.MaxFloat64, math.MaxFloat64
		left := mat[x-1][y]
		if y != min.Y {
			up = mat[x-1][y-1]
		}
		if y < max.Y-1 {
			down = mat[x-1][y+1]
		}
		val := math.Min(float64(left), math.Min(float64(up), float64(down)))
		mat[x][y] = val + (float64(e) / float64(a))
	}

	// Calculate the remaining columns iteratively
	for x := min.X + 1; x < max.X; x++ {
		for y := min.Y; y < max.Y; y++ {
			updatePoint(x, y)
		}
	}

	return mat
}

// FindLowestCostSeam uses a cumulative cost matrix to identify the seam with
// the lowest total cumulative energy.
func FindLowestCostSeam(mat [][]float64) Seam {
	width, height := len(mat), len(mat[0])
	seam := make([]Point, width)

	min, y := math.MaxFloat64, 0
	for ind, val := range mat[width-1] {
		if val < min {
			min = val
			y = ind
		}
	}

	seam[width-1] = Point{X: width - 1, Y: y}
	for x := width - 2; x >= 0; x-- {
		left := mat[x][y]
		up, down := math.MaxFloat64, math.MaxFloat64
		if y != 0 {
			up = mat[x][y-1]
		}
		if y != height-1 {
			down = mat[x][y+1]
		}

		if up < left && up < down {
			seam[x] = Point{X: x, Y: y - 1}
			y = y - 1
		} else if left < up && left < down {
			seam[x] = Point{X: x, Y: y}
			y = y
		} else {
			seam[x] = Point{X: x, Y: y + 1}
			y = y + 1
		}
	}

	return seam
}
<|endoftext|>


<commit_before>package main

import (
	"sync"
	"time"
)

type Blockchain struct {
	blocks []*Block
	mu     sync.RWMutex
}

func newBlockchain() *Blockchain {
	return &Blockchain{
		blocks: []*Block{genesisBlock},
		mu:     sync.RWMutex{},
	}
}

func (bc *Blockchain) len() int {
	return len(bc.blocks)
}

func (bc *Blockchain) getGenesisBlock() *Block {
	return bc.getBlock(0)
}

func (bc *Blockchain) getLatestBlock() *Block {
	return bc.getBlock(bc.len() - 1)
}

func (bc *Blockchain) getBlock(index int) *Block {
	bc.mu.RLock()
	defer bc.mu.RUnlock()

	return bc.blocks[index]
}

func (bc *Blockchain) generateBlock(data string) (*Block, error) {
	prevBlock := bc.getLatestBlock()
	prevBlockHash, err := prevBlock.hash()
	if err != nil {
		return nil, err
	}

	return &Block{
		Index:        prevBlock.Index + 1,
		PreviousHash: prevBlockHash,
		Timestamp:    time.Now().Unix(),
		Data:         data,
	}, nil
}

func (bc *Blockchain) addBlock(block *Block) error {
	ok, err := isValidBlock(block, bc.getLatestBlock())
	if err != nil {
		return err
	}
	if !ok {
		return ErrInvalidBlock
	}

	bc.mu.Lock()
	defer bc.mu.Unlock()

	bc.blocks = append(bc.blocks, block)

	return nil
}

func (bc *Blockchain) tryReplaceBlocks(bcNew *Blockchain) (bool, error) {
	if bcNew.len() <= bc.len() {
		return false, nil
	}

	ok, err := bcNew.isValid()
	if err != nil {
		return false, err
	}
	if !ok {
		return false, nil
	}

	bc.mu.Lock()
	defer bc.mu.Unlock()

	bc.blocks = bcNew.blocks

	return true, nil
}

func (bc *Blockchain) isValidGenesisBlock() (bool, error) {
	genesisBlockHash, err := genesisBlock.hash()
	if err != nil {
		return false, err
	}

	firstBlock := bc.getGenesisBlock()
	firstBlockHash, err := firstBlock.hash()
	if err != nil {
		return false, err
	}
	if firstBlockHash != genesisBlockHash {
		return false, nil
	}

	return true, nil
}

func (bc *Blockchain) isValid() (bool, error) {
	if bc.len() == 0 {
		return false, nil
	}

	ok, err := bc.isValidGenesisBlock()
	if err != nil {
		return false, err
	}
	if !ok {
		return false, nil
	}

	prevBlock := bc.getGenesisBlock()
	for i := 1; i < bc.len(); i++ {
		block := bc.getBlock(i)

		ok, err := isValidBlock(block, prevBlock)
		if err != nil {
			return false, err
		}
		if !ok {
			return false, nil
		}

		prevBlock = block
	}

	return true, nil
}
<commit_msg>lock chain<commit_after>package main

import (
	"sync"
	"time"
)

type Blockchain struct {
	blocks []*Block
	mu     sync.RWMutex
}

func newBlockchain() *Blockchain {
	return &Blockchain{
		blocks: []*Block{genesisBlock},
		mu:     sync.RWMutex{},
	}
}

func (bc *Blockchain) len() int {
	return len(bc.blocks)
}

func (bc *Blockchain) getGenesisBlock() *Block {
	return bc.getBlock(0)
}

func (bc *Blockchain) getLatestBlock() *Block {
	return bc.getBlock(bc.len() - 1)
}

func (bc *Blockchain) getBlock(index int) *Block {
	bc.mu.RLock()
	defer bc.mu.RUnlock()

	return bc.blocks[index]
}

func (bc *Blockchain) generateBlock(data string) (*Block, error) {
	prevBlock := bc.getLatestBlock()
	prevBlockHash, err := prevBlock.hash()
	if err != nil {
		return nil, err
	}

	return &Block{
		Index:        prevBlock.Index + 1,
		PreviousHash: prevBlockHash,
		Timestamp:    time.Now().Unix(),
		Data:         data,
	}, nil
}

func (bc *Blockchain) addBlock(block *Block) error {
	bc.mu.Lock()
	defer bc.mu.Unlock()

	ok, err := isValidBlock(block, bc.getLatestBlock())
	if err != nil {
		return err
	}
	if !ok {
		return ErrInvalidBlock
	}

	bc.blocks = append(bc.blocks, block)

	return nil
}

func (bc *Blockchain) tryReplaceBlocks(bcNew *Blockchain) (bool, error) {
	bc.mu.Lock()
	defer bc.mu.Unlock()

	if bcNew.len() <= bc.len() {
		return false, nil
	}

	ok, err := bcNew.isValid()
	if err != nil {
		return false, err
	}
	if !ok {
		return false, nil
	}

	bc.blocks = bcNew.blocks

	return true, nil
}

func (bc *Blockchain) isValidGenesisBlock() (bool, error) {
	genesisBlockHash, err := genesisBlock.hash()
	if err != nil {
		return false, err
	}

	firstBlock := bc.getGenesisBlock()
	firstBlockHash, err := firstBlock.hash()
	if err != nil {
		return false, err
	}
	if firstBlockHash != genesisBlockHash {
		return false, nil
	}

	return true, nil
}

func (bc *Blockchain) isValid() (bool, error) {
	bc.mu.RLock()
	defer bc.mu.RUnlock()

	if bc.len() == 0 {
		return false, nil
	}

	ok, err := bc.isValidGenesisBlock()
	if err != nil {
		return false, err
	}
	if !ok {
		return false, nil
	}

	prevBlock := bc.getGenesisBlock()
	for i := 1; i < bc.len(); i++ {
		block := bc.getBlock(i)

		ok, err := isValidBlock(block, prevBlock)
		if err != nil {
			return false, err
		}
		if !ok {
			return false, nil
		}

		prevBlock = block
	}

	return true, nil
}
<|endoftext|>


<commit_before>package logdb

import (
	"encoding/binary"
	"fmt"
	"io"
	"os"
	"strconv"
	"strings"

	"github.com/hashicorp/errwrap"
)

// A chunk is one memory-mapped file.
type chunk struct {
	path string

	bytes []byte
	mmapf *os.File

	// One past the ending addresses of entries in the 'bytes'
	// slice.
	//
	// This choice is because starting addresses can always be
	// calculated from ending addresses, as the first entry starts
	// at offset 0 (and there are no gaps). Ending addresses
	// cannot be calculated from starting addresses, unless the
	// ending address of the final entry is stored as well.
	ends []int32

	oldest uint64

	next uint64

	newFrom int
	delete  bool
}

// Delete the files associated with a chunk.
func (c *chunk) closeAndRemove() error {
	if err := closeAndRemove(c.mmapf); err != nil {
		return err
	}
	return os.Remove(c.metaFilePath())
}

const (
	chunkPrefix      = "chunk"
	metaSuffix       = "meta"
	sep              = "_"
	initialChunkFile = chunkPrefix + sep + "0" + sep + "1"
)

// Get the meta file path associated with a chunk data file path.
func metaFilePath(dataFilePath string) string {
	return dataFilePath + sep + metaSuffix
}

// Get the meta file path associated with a chunk.
func (c *chunk) metaFilePath() string {
	return metaFilePath(c.path)
}

// Check if a file basename is a chunk data file.
//
// A valid chunk filename consists of the chunkPrefix followed by one
// or more digits, with no leading zeroes.
func isBasenameChunkDataFile(basename string) bool {
	bits := strings.Split(basename, chunkPrefix+sep)
	// In the form chunkPrefix[.+]
	if len(bits) != 2 || len(bits[0]) != 0 || len(bits[1]) == 0 {
		return false
	}

	bits = strings.Split(bits[1], sep)

	if len(bits) != 2 {
		return false
	}

	// Must be [0-9]+_[0-9]+]
	if len(bits[0]) == 0 || len(bits[1]) == 0 {
		return false
	}
	first, err := strconv.ParseUint(bits[0], 10, 0)
	if err != nil {
		return false
	}
	if _, err := strconv.ParseUint(bits[1], 10, 0); err != nil {
		return false
	}

	// Leading zeroes are disallowed.
	if bits[0][0] == '0' {
		return first == 0
	}

	return true
}

// Given a chunk, get the filename of the next chunk.
//
// This function panics if the chunk path is invalid. This should
// never happen unless openChunkSliceDB or isChunkDataFile is broken.
func (c *chunk) nextDataFileName(oldest uint64) string {
	bits := strings.Split(c.path, "/"+chunkPrefix+sep)
	if len(bits) < 2 {
		panic("malformed chunk file name: " + c.path)
	}

	bits = strings.Split(bits[len(bits)-1], sep)
	if len(bits) != 2 {
		panic("malformed chunk file name: " + c.path)
	}

	num, err := strconv.ParseUint(bits[0], 10, 0)
	if err != nil {
		panic("malformed chunk file name: " + c.path)
	}

	return fmt.Sprintf("%s%s%v%s%v", chunkPrefix, sep, num+1, sep, oldest)
}

// Create the files for a new chunk. As an empty chunk is not allowed,
// it is assumed that an entry will be immediately written.
func createChunkFiles(dataFilePath string, chunkSize uint32, oldest uint64) error {
	// Create the chunk files.
	if err := createFile(dataFilePath, chunkSize); err != nil {
		return err
	}
	file, err := os.OpenFile(metaFilePath(dataFilePath), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
	file.Close()
	return err
}

// Open a chunk file
func openChunkFile(basedir string, fi os.FileInfo, priorChunk *chunk, chunkSize uint32) (chunk, error) {
	chunk := chunk{path: basedir + "/" + fi.Name()}
	// Get the oldest ID from the file name
	if !isBasenameChunkDataFile(fi.Name()) {
		return chunk, fmt.Errorf("invalid chunk data file name: %s", fi.Name())
	}
	// This does no validation because isBasenameChunkDataFile took care of that.
	nameBits := strings.Split(fi.Name(), sep)
	oldnum, _ := strconv.ParseUint(nameBits[2], 10, 0)
	chunk.oldest = uint64(oldnum)

	// mmap the data file
	mmapf, bytes, err := mmap(chunk.path)
	if err != nil {
		return chunk, &ReadError{err}
	}
	if uint32(len(bytes)) != chunkSize {
		return chunk, &FormatError{
			FilePath: chunk.path,
			Err:      fmt.Errorf("incorrect file size (expected %v got %v)", chunkSize, uint32(len(bytes))),
		}
	}
	chunk.bytes = bytes
	chunk.mmapf = mmapf

	// read the ending address metadata
	mfile, err := os.Open((&chunk).metaFilePath())
	if err != nil {
		return chunk, &ReadError{err}
	}
	defer mfile.Close()
	for {
		// metadata is in the format [index int32][end int32]
		// metadata ends at EOF
		// If the indices go backwards, that means entries have been rolled back
		var idx int32
		var this int32
		if err := binary.Read(mfile, binary.LittleEndian, &idx); err != nil {
			if err == io.EOF {
				break
			}
			return chunk, &FormatError{
				FilePath: (&chunk).metaFilePath(),
				Err:      errwrap.Wrapf("unexpected error reading chunk metadata: {{err}}", err),
			}
		}
		if idx > int32(len(chunk.ends)) {
			return chunk, &FormatError{
				FilePath: (&chunk).metaFilePath(),
				Err:      fmt.Errorf("entry index too large (expected <=%v, got %v)", len(chunk.ends), idx),
			}
		}
		if err := binary.Read(mfile, binary.LittleEndian, &this); err != nil {
			if err == io.EOF {
				// EOF here means that syncing failed, so just forget this last entry.
				break
			}
			return chunk, &FormatError{
				FilePath: (&chunk).metaFilePath(),
				Err:      err,
			}
		}
		if idx < int32(len(chunk.ends)) {
			if idx == 0 {
				chunk.ends = nil
			} else {
				chunk.ends = chunk.ends[0:idx]
			}
		}
		if idx > 0 && this < chunk.ends[idx-1] {
			return chunk, &FormatError{
				FilePath: (&chunk).metaFilePath(),
				Err:      fmt.Errorf("entry ending positions are not monotonically increasing (prior %v got %v)", chunk.ends[idx-1], this),
			}
		}
		chunk.ends = append(chunk.ends, this)
	}

	// Chunk oldest/next IDs must match: there can be no gaps!
	if priorChunk != nil && chunk.oldest != priorChunk.next {
		return chunk, &FormatError{
			FilePath: (&chunk).metaFilePath(),
			Err:      fmt.Errorf("discontinuity in entry IDs (expected %v got %v)", priorChunk.next, chunk.oldest),
		}
	}

	chunk.next = chunk.oldest + uint64(len(chunk.ends))
	return chunk, nil
}

// Write a chunk to disk.
func (c *chunk) sync() error {
	// To ensure ACID, sync the data first and only then the
	// metadata. This means that if there is a failure between the
	// two syncs, even if the newly-written data is corrupt, there
	// will be no metadata referring to it, and so it will be
	// invisible to the database when next opened.
	if err := fsync(c.mmapf); err != nil {
		return err
	}

	// Write the new end points.
	for i := c.newFrom; i < len(c.ends); i++ {
		if err := appendFile(c.metaFilePath(), int32(i)); err != nil {
			return err
		}
		if err := appendFile(c.metaFilePath(), c.ends[i]); err != nil {
			return err
		}
	}
	c.newFrom = len(c.ends)

	return nil
}
<commit_msg>Handle lack of a / in data file paths<commit_after>package logdb

import (
	"encoding/binary"
	"fmt"
	"io"
	"os"
	"strconv"
	"strings"

	"github.com/hashicorp/errwrap"
)

// A chunk is one memory-mapped file.
type chunk struct {
	path string

	bytes []byte
	mmapf *os.File

	// One past the ending addresses of entries in the 'bytes'
	// slice.
	//
	// This choice is because starting addresses can always be
	// calculated from ending addresses, as the first entry starts
	// at offset 0 (and there are no gaps). Ending addresses
	// cannot be calculated from starting addresses, unless the
	// ending address of the final entry is stored as well.
	ends []int32

	oldest uint64

	next uint64

	newFrom int
	delete  bool
}

// Delete the files associated with a chunk.
func (c *chunk) closeAndRemove() error {
	if err := closeAndRemove(c.mmapf); err != nil {
		return err
	}
	return os.Remove(c.metaFilePath())
}

const (
	chunkPrefix      = "chunk"
	metaSuffix       = "meta"
	sep              = "_"
	initialChunkFile = chunkPrefix + sep + "0" + sep + "1"
)

// Get the meta file path associated with a chunk data file path.
func metaFilePath(dataFilePath string) string {
	return dataFilePath + sep + metaSuffix
}

// Get the meta file path associated with a chunk.
func (c *chunk) metaFilePath() string {
	return metaFilePath(c.path)
}

// Check if a file basename is a chunk data file.
//
// A valid chunk filename consists of the chunkPrefix followed by one
// or more digits, with no leading zeroes.
func isBasenameChunkDataFile(basename string) bool {
	bits := strings.Split(basename, chunkPrefix+sep)
	// In the form chunkPrefix[.+]
	if len(bits) != 2 || len(bits[0]) != 0 || len(bits[1]) == 0 {
		return false
	}

	bits = strings.Split(bits[1], sep)

	if len(bits) != 2 {
		return false
	}

	// Must be [0-9]+_[0-9]+]
	if len(bits[0]) == 0 || len(bits[1]) == 0 {
		return false
	}
	first, err := strconv.ParseUint(bits[0], 10, 0)
	if err != nil {
		return false
	}
	if _, err := strconv.ParseUint(bits[1], 10, 0); err != nil {
		return false
	}

	// Leading zeroes are disallowed.
	if bits[0][0] == '0' {
		return first == 0
	}

	return true
}

// Given a chunk, get the filename of the next chunk.
//
// This function panics if the chunk path is invalid. This should
// never happen unless openChunkSliceDB or isChunkDataFile is broken.
func (c *chunk) nextDataFileName(oldest uint64) string {
	// If there are directories in the path, correctly identify the basename.
	firstSep := chunkPrefix + sep
	if strings.ContainsRune(c.path, '/') {
		firstSep = "/" + firstSep
	}

	bits := strings.Split(c.path, firstSep)
	if len(bits) < 2 {
		panic("malformed chunk file name: " + c.path)
	}

	bits = strings.Split(bits[len(bits)-1], sep)
	if len(bits) != 2 {
		panic("malformed chunk file name: " + c.path)
	}

	num, err := strconv.ParseUint(bits[0], 10, 0)
	if err != nil {
		panic("malformed chunk file name: " + c.path)
	}

	return fmt.Sprintf("%s%s%v%s%v", chunkPrefix, sep, num+1, sep, oldest)
}

// Create the files for a new chunk. As an empty chunk is not allowed,
// it is assumed that an entry will be immediately written.
func createChunkFiles(dataFilePath string, chunkSize uint32, oldest uint64) error {
	// Create the chunk files.
	if err := createFile(dataFilePath, chunkSize); err != nil {
		return err
	}
	file, err := os.OpenFile(metaFilePath(dataFilePath), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
	file.Close()
	return err
}

// Open a chunk file
func openChunkFile(basedir string, fi os.FileInfo, priorChunk *chunk, chunkSize uint32) (chunk, error) {
	chunk := chunk{path: basedir + "/" + fi.Name()}
	// Get the oldest ID from the file name
	if !isBasenameChunkDataFile(fi.Name()) {
		return chunk, fmt.Errorf("invalid chunk data file name: %s", fi.Name())
	}
	// This does no validation because isBasenameChunkDataFile took care of that.
	nameBits := strings.Split(fi.Name(), sep)
	oldnum, _ := strconv.ParseUint(nameBits[2], 10, 0)
	chunk.oldest = uint64(oldnum)

	// mmap the data file
	mmapf, bytes, err := mmap(chunk.path)
	if err != nil {
		return chunk, &ReadError{err}
	}
	if uint32(len(bytes)) != chunkSize {
		return chunk, &FormatError{
			FilePath: chunk.path,
			Err:      fmt.Errorf("incorrect file size (expected %v got %v)", chunkSize, uint32(len(bytes))),
		}
	}
	chunk.bytes = bytes
	chunk.mmapf = mmapf

	// read the ending address metadata
	mfile, err := os.Open((&chunk).metaFilePath())
	if err != nil {
		return chunk, &ReadError{err}
	}
	defer mfile.Close()
	for {
		// metadata is in the format [index int32][end int32]
		// metadata ends at EOF
		// If the indices go backwards, that means entries have been rolled back
		var idx int32
		var this int32
		if err := binary.Read(mfile, binary.LittleEndian, &idx); err != nil {
			if err == io.EOF {
				break
			}
			return chunk, &FormatError{
				FilePath: (&chunk).metaFilePath(),
				Err:      errwrap.Wrapf("unexpected error reading chunk metadata: {{err}}", err),
			}
		}
		if idx > int32(len(chunk.ends)) {
			return chunk, &FormatError{
				FilePath: (&chunk).metaFilePath(),
				Err:      fmt.Errorf("entry index too large (expected <=%v, got %v)", len(chunk.ends), idx),
			}
		}
		if err := binary.Read(mfile, binary.LittleEndian, &this); err != nil {
			if err == io.EOF {
				// EOF here means that syncing failed, so just forget this last entry.
				break
			}
			return chunk, &FormatError{
				FilePath: (&chunk).metaFilePath(),
				Err:      err,
			}
		}
		if idx < int32(len(chunk.ends)) {
			if idx == 0 {
				chunk.ends = nil
			} else {
				chunk.ends = chunk.ends[0:idx]
			}
		}
		if idx > 0 && this < chunk.ends[idx-1] {
			return chunk, &FormatError{
				FilePath: (&chunk).metaFilePath(),
				Err:      fmt.Errorf("entry ending positions are not monotonically increasing (prior %v got %v)", chunk.ends[idx-1], this),
			}
		}
		chunk.ends = append(chunk.ends, this)
	}

	// Chunk oldest/next IDs must match: there can be no gaps!
	if priorChunk != nil && chunk.oldest != priorChunk.next {
		return chunk, &FormatError{
			FilePath: (&chunk).metaFilePath(),
			Err:      fmt.Errorf("discontinuity in entry IDs (expected %v got %v)", priorChunk.next, chunk.oldest),
		}
	}

	chunk.next = chunk.oldest + uint64(len(chunk.ends))
	return chunk, nil
}

// Write a chunk to disk.
func (c *chunk) sync() error {
	// To ensure ACID, sync the data first and only then the
	// metadata. This means that if there is a failure between the
	// two syncs, even if the newly-written data is corrupt, there
	// will be no metadata referring to it, and so it will be
	// invisible to the database when next opened.
	if err := fsync(c.mmapf); err != nil {
		return err
	}

	// Write the new end points.
	for i := c.newFrom; i < len(c.ends); i++ {
		if err := appendFile(c.metaFilePath(), int32(i)); err != nil {
			return err
		}
		if err := appendFile(c.metaFilePath(), c.ends[i]); err != nil {
			return err
		}
	}
	c.newFrom = len(c.ends)

	return nil
}
<|endoftext|>


<commit_before>package storm

// Close the database
func (s *DB) Close() {
	s.Bolt.Close()
}
<commit_msg>Fix Close signature<commit_after>package storm

// Close the database
func (s *DB) Close() error {
	return s.Bolt.Close()
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/sachaos/todoist/lib"
	"github.com/urfave/cli"
	"strconv"
)

func Close(config Config, c *cli.Context) error {
	var sync lib.Sync
	item_ids := []int{}
	for _, arg := range c.Args() {
		item_id, err := strconv.Atoi(arg)
		if err != nil {
			return err
		}
		item_ids = append(item_ids, item_id)
	}

	err := lib.CloseItem(item_ids, config.Token)
	if err != nil {
		return err
	}

	sync, err = lib.FetchCache(config.Token)
	if err != nil {
		return CommandFailed
	}
	err = lib.SaveCache(default_cache_path, sync)
	if err != nil {
		return CommandFailed
	}

	return nil
}
<commit_msg>Ignore when no args<commit_after>package main

import (
	"github.com/sachaos/todoist/lib"
	"github.com/urfave/cli"
	"strconv"
)

func Close(config Config, c *cli.Context) error {
	var sync lib.Sync
	item_ids := []int{}
	for _, arg := range c.Args() {
		item_id, err := strconv.Atoi(arg)
		if err != nil {
			return err
		}
		item_ids = append(item_ids, item_id)
	}

	if len(item_ids) == 0 {
		return CommandFailed
	}

	err := lib.CloseItem(item_ids, config.Token)
	if err != nil {
		return CommandFailed
	}

	sync, err = lib.FetchCache(config.Token)
	if err != nil {
		return CommandFailed
	}
	err = lib.SaveCache(default_cache_path, sync)
	if err != nil {
		return CommandFailed
	}

	return nil
}
<|endoftext|>


<commit_before>package agraph

import "os"

type Codec interface {
	decode() []byte
	encode() []byte
}

type Mp3 struct {
	file *os.File
}

func (mp3 Mp3) decode() []byte {
	return []byte("Hello, world!")
}

func (mp3 Mp3) encode() []byte {
	return []byte("Hello, world!")
}
<commit_msg>drop mp3 encode/decode<commit_after><|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"
	"encoding/json"
	"time"

	"github.com/openblockchain/obc-peer/openchain/chaincode/shim"
)

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

var marbleIndex []string						//store marbles here, b/c we need this
var _allIndex []string							//store all variables names here, b/c its handy for debug
var _all string = "_all"						//key name for above. tracks all variables in chaincode state

type Marble struct{
	Name string `json:"name"`					//the fieldtags are needed to keep case from bouncing around
	Color string `json:"color"`
	Size int `json:"size"`
	User string `json:"user"`
}

type Description struct{
	Color string `json:"color"`
	Size int `json:"size"`
}

type AnOpenTrade struct{
	User string `json:"user"`					//user who created the open trade order
	Timestamp int64 `json:"timestamp"`			//utc timestamp of creation
	Want Description  `json:"want"`				//description of desired marble
	Willing []Description `json:"willing"`		//array of marbles willing to trade away
}

type AllTrades struct{
	OpenTrades []AnOpenTrade `json:"open_trades"`
}

var trades AllTrades

// ============================================================================================================================
// Init - reset all the things
// ============================================================================================================================
func (t *SimpleChaincode) init(stub *shim.ChaincodeStub, args []string) ([]byte, error) {
	var Aval int
	var err error

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

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

	// Write the state to the ledger
	err = stub.PutState("abc", []byte(strconv.Itoa(Aval)))				//making a test var "abc", I find it handy to read/write to it right away to test the network
	if err != nil {
		return nil, err
	}

	_allIndex = _allIndex[:0]											//clear the _all variables index
	jsonAsBytes1, _ := json.Marshal(_allIndex)
	err = stub.PutState(_all, jsonAsBytes1)
	if err != nil {
		return nil, err
	}

	marbleIndex = marbleIndex[:0]										//clear the marble index
	jsonAsBytes, _ := json.Marshal(marbleIndex)
	err = stub.PutState("marbleIndex", jsonAsBytes)
	if err != nil {
		return nil, err
	}

	return nil, nil
}

// ============================================================================================================================
// Run - Our entry point
// ============================================================================================================================
func (t *SimpleChaincode) Run(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) {
	fmt.Println("run is running " + function)

	// Handle different functions
	if function == "init" {													//initialize the chaincode state, used as reset
		return t.init(stub, args)
	} else if function == "delete" {										//deletes an entity from its state
		return t.Delete(stub, args)
	} else if function == "write" {											//writes a value to the chaincode state
		return t.Write(stub, args)
	} else if function == "init_marble" {									//create a new marble
		return t.init_marble(stub, args)
	} else if function == "set_user" {										//change owner of a marble
		return t.set_user(stub, args)
	} else if function == "open_trade" {									//create a new trade order
		return t.open_trade(stub, args)
	} else if function == "perform_trade" {									//forfill an open trade order
		return t.perform_trade(stub, args)
	}
	fmt.Println("run did not find func: " + function)						//error

	return nil, errors.New("Received unknown function invocation")
}

// ============================================================================================================================
// Delete - remove 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")
	}

	name := args[0]
	err := stub.DelState(name)													//remove the key from chaincode state
	if err != nil {
		return nil, errors.New("Failed to delete state")
	}

	//remove marble from index
	for i,val := range marbleIndex{
		fmt.Println(strconv.Itoa(i) + " - looking at " + val + " for " + name)
		if val == name{															//find the correct marble
			fmt.Println("found marble")
			marbleIndex = append(marbleIndex[:i], marbleIndex[i+1:]...)			//remove it
			for x:= range marbleIndex{											//debug prints...
				fmt.Println(string(x) + " - " + marbleIndex[x])
			}
			break
		}
	}
	jsonAsBytes, _ := json.Marshal(marbleIndex)									//save new index
	err = stub.PutState("marbleIndex", jsonAsBytes)

	return nil, nil
}

// ============================================================================================================================
// Query - read a variable from chaincode state - (aka read)
// ============================================================================================================================
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 name, jsonResp string
	var err error

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

	name = args[0]
	valAsbytes, err := stub.GetState(name)									//get the var from chaincode state
	if err != nil {
		jsonResp = "{\"Error\":\"Failed to get state for " + name + "\"}"
		return nil, errors.New(jsonResp)
	}

	return valAsbytes, nil													//send it onward
}

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

// ============================================================================================================================
// Write - write variable into chaincode state
// ============================================================================================================================
func (t *SimpleChaincode) Write(stub *shim.ChaincodeStub, args []string) ([]byte, error) {
	var name, value string // Entities
	var err error
	fmt.Println("running write()")

	if len(args) != 2 {
		return nil, errors.New("Incorrect number of arguments. Expecting 2. name of the variable and value to set")
	}

	name = args[0]															//rename for funsies
	value = args[1]
	err = stub.PutState(name, []byte(value))								//write the variable into the chaincode state
	if err != nil {
		return nil, err
	}
	t.remember_me(stub, name)

	return nil, nil
}

// ============================================================================================================================
// Remember Me - remember the name of variables we stored in ledger
// ============================================================================================================================
func (t *SimpleChaincode) remember_me(stub *shim.ChaincodeStub, name string) ([]byte, error) {
	var err error

	_allIndex = append(_allIndex, name)										//add var name to index list
	jsonAsBytes, _ := json.Marshal(_allIndex)
	err = stub.PutState(_all, jsonAsBytes)									//store it
	if err != nil {
		return nil, err
	}

	return nil, nil
}

// ============================================================================================================================
// Init Marble
// ============================================================================================================================
func (t *SimpleChaincode) init_marble(stub *shim.ChaincodeStub, args []string) ([]byte, error) {
	var err error

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

	val, err := strconv.Atoi(args[2])
	if err != nil {
		val = 16															//default value
	}
	str := `{"name": "` + args[0] + `", "color": "` + args[1] + `", "size": ` + strconv.Itoa(val) + `, "user": "` + args[3] + `"}`

	err = stub.PutState(args[0], []byte(str))								//store marble with id as key
	if err != nil {
		return nil, err
	}
	t.remember_me(stub, args[0])

	marbleIndex = append(marbleIndex, args[0])								//add marble name to index list
	jsonAsBytes, _ := json.Marshal(marbleIndex)
	err = stub.PutState("marbleIndex", jsonAsBytes)							//store name of marble

	return nil, nil
}

// ============================================================================================================================
// Set User Permission on Marble
// ============================================================================================================================
func (t *SimpleChaincode) set_user(stub *shim.ChaincodeStub, args []string) ([]byte, error) {
	var err error

	// "asdf", "bob"
	if len(args) < 2 {
		return nil, errors.New("Incorrect number of arguments. Expecting 2")
	}

	marbleAsBytes, err := stub.GetState(args[0])
	if err != nil {
		return nil, errors.New("Failed to get thing")
	}
	res := Marble{}
	json.Unmarshal(marbleAsBytes, &res)										//un stringify it aka JSON.parse()
	fmt.Println(res)
	res.User = args[1]														//change the user

	jsonAsBytes, _ := json.Marshal(res)
	err = stub.PutState(args[0], jsonAsBytes)								//rewrite the marble with id as key
	if err != nil {
		return nil, err
	}

	return nil, nil
}

// ============================================================================================================================
// Open Trade - create an open trade for a marble you want with marbles you have
// ============================================================================================================================
func (t *SimpleChaincode) open_trade(stub *shim.ChaincodeStub, args []string) ([]byte, error) {
	var err error

	//"bob", "blue", "16", "red", "16"
	if len(args) < 5 {
		return nil, errors.New("Incorrect number of arguments. Expecting like 5?")
	}

	size1, err := strconv.Atoi(args[2])
	if err != nil {
		return nil, errors.New("3rd argument must be a numeric string")
	}
	size2, err := strconv.Atoi(args[4])
	if err != nil {
		return nil, errors.New("5th argument must be a numeric string")
	}

	open := AnOpenTrade{};
	open.User = args[0];
	open.Timestamp = time.Now().UnixNano();										//use this as an ID
	open.Want.Color = args[1];
	open.Want.Size =  size1;
	fmt.Println("! start open trade")
	jsonAsBytes, _ := json.Marshal(open)
	err = stub.PutState("_debug1", jsonAsBytes)

	trade_away := Description{};
	trade_away.Color = args[3];
	trade_away.Size =  size2;
	fmt.Println("! created trade_away")
	jsonAsBytes, _ = json.Marshal(trade_away)
	err = stub.PutState("_debug2", jsonAsBytes)

	open.Willing = append(open.Willing, trade_away)
	fmt.Println("! appended willing to open")
	jsonAsBytes, _ = json.Marshal(open)
	err = stub.PutState("_debug3", jsonAsBytes)

	trades.OpenTrades = append(trades.OpenTrades, open);						//append to open trades
	fmt.Println("! appended open to trades")
	jsonAsBytes, _ = json.Marshal(trades)
	err = stub.PutState("_opentrades", jsonAsBytes)								//rewrite open orders
	if err != nil {
		return nil, err
	}
	fmt.Println("! open trade success ")
	return nil, nil
}

// ============================================================================================================================
// Perform Trade - close an open trade and move ownership
// ============================================================================================================================
func (t *SimpleChaincode) perform_trade(stub *shim.ChaincodeStub, args []string) ([]byte, error) {
	var err error

	//"bob", "444444444444", "asdf"
	if len(args) < 3 {
		return nil, errors.New("Incorrect number of arguments. Expecting 3")
	}

	fmt.Println("! start close trade")
	timestamp, err := strconv.ParseInt(args[1], 10, 64)
	if err != nil {
		return nil, errors.New("2nd argument must be a numeric string")
	}

	for i := range trades.OpenTrades{														//look for the trade
		fmt.Println("looking at " + strconv.FormatInt(trades.OpenTrades[i].Timestamp, 10) + " for " + strconv.FormatInt(timestamp, 10))
		if trades.OpenTrades[i].Timestamp == timestamp{
			fmt.Println("found trade");

			t.set_user(stub, []string{args[0], args[2]})

			trades.OpenTrades = append(trades.OpenTrades[:i], trades.OpenTrades[i+1:]...)	//remove trade
			jsonAsBytes, _ := json.Marshal(trades)
			err = stub.PutState("_opentrades", jsonAsBytes)									//rewrite open orders
			if err != nil {
				return nil, err
			}
		}
	}
	fmt.Println("! close trade success ")
	return nil, nil
}<commit_msg>- timestamp is now ms not ns<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"
	"encoding/json"
	"time"

	"github.com/openblockchain/obc-peer/openchain/chaincode/shim"
)

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

var marbleIndex []string						//store marbles here, b/c we need this
var _allIndex []string							//store all variables names here, b/c its handy for debug
var _all string = "_all"						//key name for above. tracks all variables in chaincode state

type Marble struct{
	Name string `json:"name"`					//the fieldtags are needed to keep case from bouncing around
	Color string `json:"color"`
	Size int `json:"size"`
	User string `json:"user"`
}

type Description struct{
	Color string `json:"color"`
	Size int `json:"size"`
}

type AnOpenTrade struct{
	User string `json:"user"`					//user who created the open trade order
	Timestamp int64 `json:"timestamp"`			//utc timestamp of creation
	Want Description  `json:"want"`				//description of desired marble
	Willing []Description `json:"willing"`		//array of marbles willing to trade away
}

type AllTrades struct{
	OpenTrades []AnOpenTrade `json:"open_trades"`
}

var trades AllTrades

// ============================================================================================================================
// Init - reset all the things
// ============================================================================================================================
func (t *SimpleChaincode) init(stub *shim.ChaincodeStub, args []string) ([]byte, error) {
	var Aval int
	var err error

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

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

	// Write the state to the ledger
	err = stub.PutState("abc", []byte(strconv.Itoa(Aval)))				//making a test var "abc", I find it handy to read/write to it right away to test the network
	if err != nil {
		return nil, err
	}

	_allIndex = _allIndex[:0]											//clear the _all variables index
	jsonAsBytes1, _ := json.Marshal(_allIndex)
	err = stub.PutState(_all, jsonAsBytes1)
	if err != nil {
		return nil, err
	}

	marbleIndex = marbleIndex[:0]										//clear the marble index
	jsonAsBytes, _ := json.Marshal(marbleIndex)
	err = stub.PutState("marbleIndex", jsonAsBytes)
	if err != nil {
		return nil, err
	}

	return nil, nil
}

// ============================================================================================================================
// Run - Our entry point
// ============================================================================================================================
func (t *SimpleChaincode) Run(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) {
	fmt.Println("run is running " + function)

	// Handle different functions
	if function == "init" {													//initialize the chaincode state, used as reset
		return t.init(stub, args)
	} else if function == "delete" {										//deletes an entity from its state
		return t.Delete(stub, args)
	} else if function == "write" {											//writes a value to the chaincode state
		return t.Write(stub, args)
	} else if function == "init_marble" {									//create a new marble
		return t.init_marble(stub, args)
	} else if function == "set_user" {										//change owner of a marble
		return t.set_user(stub, args)
	} else if function == "open_trade" {									//create a new trade order
		return t.open_trade(stub, args)
	} else if function == "perform_trade" {									//forfill an open trade order
		return t.perform_trade(stub, args)
	}
	fmt.Println("run did not find func: " + function)						//error

	return nil, errors.New("Received unknown function invocation")
}

// ============================================================================================================================
// Delete - remove 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")
	}

	name := args[0]
	err := stub.DelState(name)													//remove the key from chaincode state
	if err != nil {
		return nil, errors.New("Failed to delete state")
	}

	//remove marble from index
	for i,val := range marbleIndex{
		fmt.Println(strconv.Itoa(i) + " - looking at " + val + " for " + name)
		if val == name{															//find the correct marble
			fmt.Println("found marble")
			marbleIndex = append(marbleIndex[:i], marbleIndex[i+1:]...)			//remove it
			for x:= range marbleIndex{											//debug prints...
				fmt.Println(string(x) + " - " + marbleIndex[x])
			}
			break
		}
	}
	jsonAsBytes, _ := json.Marshal(marbleIndex)									//save new index
	err = stub.PutState("marbleIndex", jsonAsBytes)

	return nil, nil
}

// ============================================================================================================================
// Query - read a variable from chaincode state - (aka read)
// ============================================================================================================================
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 name, jsonResp string
	var err error

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

	name = args[0]
	valAsbytes, err := stub.GetState(name)									//get the var from chaincode state
	if err != nil {
		jsonResp = "{\"Error\":\"Failed to get state for " + name + "\"}"
		return nil, errors.New(jsonResp)
	}

	return valAsbytes, nil													//send it onward
}

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

// ============================================================================================================================
// Write - write variable into chaincode state
// ============================================================================================================================
func (t *SimpleChaincode) Write(stub *shim.ChaincodeStub, args []string) ([]byte, error) {
	var name, value string // Entities
	var err error
	fmt.Println("running write()")

	if len(args) != 2 {
		return nil, errors.New("Incorrect number of arguments. Expecting 2. name of the variable and value to set")
	}

	name = args[0]															//rename for funsies
	value = args[1]
	err = stub.PutState(name, []byte(value))								//write the variable into the chaincode state
	if err != nil {
		return nil, err
	}
	t.remember_me(stub, name)

	return nil, nil
}

// ============================================================================================================================
// Remember Me - remember the name of variables we stored in ledger
// ============================================================================================================================
func (t *SimpleChaincode) remember_me(stub *shim.ChaincodeStub, name string) ([]byte, error) {
	var err error

	_allIndex = append(_allIndex, name)										//add var name to index list
	jsonAsBytes, _ := json.Marshal(_allIndex)
	err = stub.PutState(_all, jsonAsBytes)									//store it
	if err != nil {
		return nil, err
	}

	return nil, nil
}

// ============================================================================================================================
// Init Marble
// ============================================================================================================================
func (t *SimpleChaincode) init_marble(stub *shim.ChaincodeStub, args []string) ([]byte, error) {
	var err error

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

	val, err := strconv.Atoi(args[2])
	if err != nil {
		val = 16															//default value
	}
	str := `{"name": "` + args[0] + `", "color": "` + args[1] + `", "size": ` + strconv.Itoa(val) + `, "user": "` + args[3] + `"}`

	err = stub.PutState(args[0], []byte(str))								//store marble with id as key
	if err != nil {
		return nil, err
	}
	t.remember_me(stub, args[0])

	marbleIndex = append(marbleIndex, args[0])								//add marble name to index list
	jsonAsBytes, _ := json.Marshal(marbleIndex)
	err = stub.PutState("marbleIndex", jsonAsBytes)							//store name of marble

	return nil, nil
}

// ============================================================================================================================
// Set User Permission on Marble
// ============================================================================================================================
func (t *SimpleChaincode) set_user(stub *shim.ChaincodeStub, args []string) ([]byte, error) {
	var err error

	// "asdf", "bob"
	if len(args) < 2 {
		return nil, errors.New("Incorrect number of arguments. Expecting 2")
	}

	marbleAsBytes, err := stub.GetState(args[0])
	if err != nil {
		return nil, errors.New("Failed to get thing")
	}
	res := Marble{}
	json.Unmarshal(marbleAsBytes, &res)										//un stringify it aka JSON.parse()
	fmt.Println(res)
	res.User = args[1]														//change the user

	jsonAsBytes, _ := json.Marshal(res)
	err = stub.PutState(args[0], jsonAsBytes)								//rewrite the marble with id as key
	if err != nil {
		return nil, err
	}

	return nil, nil
}

// ============================================================================================================================
// Open Trade - create an open trade for a marble you want with marbles you have
// ============================================================================================================================
func (t *SimpleChaincode) open_trade(stub *shim.ChaincodeStub, args []string) ([]byte, error) {
	var err error

	//"bob", "blue", "16", "red", "16"
	if len(args) < 5 {
		return nil, errors.New("Incorrect number of arguments. Expecting like 5?")
	}

	size1, err := strconv.Atoi(args[2])
	if err != nil {
		return nil, errors.New("3rd argument must be a numeric string")
	}
	size2, err := strconv.Atoi(args[4])
	if err != nil {
		return nil, errors.New("5th argument must be a numeric string")
	}

	open := AnOpenTrade{};
	open.User = args[0];
	open.Timestamp = makeTimestamp()											//use this as an ID
	open.Want.Color = args[1];
	open.Want.Size =  size1;
	fmt.Println("! start open trade")
	jsonAsBytes, _ := json.Marshal(open)
	err = stub.PutState("_debug1", jsonAsBytes)

	trade_away := Description{};
	trade_away.Color = args[3];
	trade_away.Size =  size2;
	fmt.Println("! created trade_away")
	jsonAsBytes, _ = json.Marshal(trade_away)
	err = stub.PutState("_debug2", jsonAsBytes)

	open.Willing = append(open.Willing, trade_away)
	fmt.Println("! appended willing to open")
	jsonAsBytes, _ = json.Marshal(open)
	err = stub.PutState("_debug3", jsonAsBytes)

	trades.OpenTrades = append(trades.OpenTrades, open);						//append to open trades
	fmt.Println("! appended open to trades")
	jsonAsBytes, _ = json.Marshal(trades)
	err = stub.PutState("_opentrades", jsonAsBytes)								//rewrite open orders
	if err != nil {
		return nil, err
	}
	fmt.Println("! open trade success ")
	return nil, nil
}

// ============================================================================================================================
// Perform Trade - close an open trade and move ownership
// ============================================================================================================================
func (t *SimpleChaincode) perform_trade(stub *shim.ChaincodeStub, args []string) ([]byte, error) {
	var err error

	//"bob", "444444444444", "asdf"
	if len(args) < 3 {
		return nil, errors.New("Incorrect number of arguments. Expecting 3")
	}

	fmt.Println("! start close trade")
	timestamp, err := strconv.ParseInt(args[1], 10, 64)
	if err != nil {
		return nil, errors.New("2nd argument must be a numeric string")
	}

	for i := range trades.OpenTrades{														//look for the trade
		fmt.Println("looking at " + strconv.FormatInt(trades.OpenTrades[i].Timestamp, 10) + " for " + strconv.FormatInt(timestamp, 10))
		if trades.OpenTrades[i].Timestamp == timestamp{
			fmt.Println("found trade");

			t.set_user(stub, []string{args[0], args[2]})

			trades.OpenTrades = append(trades.OpenTrades[:i], trades.OpenTrades[i+1:]...)	//remove trade
			jsonAsBytes, _ := json.Marshal(trades)
			err = stub.PutState("_opentrades", jsonAsBytes)									//rewrite open orders
			if err != nil {
				return nil, err
			}
		}
	}
	fmt.Println("! close trade success ")
	return nil, nil
}

func makeTimestamp() int64 {
    return time.Now().UnixNano() / (int64(time.Millisecond)/int64(time.Nanosecond))
}<|endoftext|>


<commit_before>package app

import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"encoding/base64"
	"encoding/json"
	"errors"
	"io"
	"sync"
)

type jsStorage struct {
	name  string
	key   []byte
	mutex sync.RWMutex
}

func newJSStorage(name string) *jsStorage {
	u := Window().URL()

	key := []byte(u.Scheme + "(*_*)" + u.Host)
	for len(key) < 32 {
		key = append(key, 'o')
	}
	key = key[:32]

	return &jsStorage{
		name: name,
		key:  key,
	}
}

func (s *jsStorage) Set(k string, v interface{}) error {
	s.mutex.Lock()
	defer s.mutex.Unlock()

	b, err := json.Marshal(v)
	if err != nil {
		return err
	}

	b, err = encrypt(b, s.key)
	if err != nil {
		return err
	}

	item := base64.StdEncoding.EncodeToString(b)
	Window().Get(s.name).Call("setItem", k, item)
	return nil
}

func (s *jsStorage) Get(k string, v interface{}) error {
	s.mutex.RLock()
	defer s.mutex.RUnlock()

	item := Window().Get(s.name).Call("getItem", k)
	if !item.Truthy() {
		return nil
	}

	b, err := base64.StdEncoding.DecodeString(item.String())
	if err != nil {
		return err
	}

	if b, err = decrypt(b, s.key); err != nil {
		return err
	}

	return json.Unmarshal(b, v)
}

func (s *jsStorage) Del(k string) {
	s.mutex.Lock()
	defer s.mutex.Unlock()

	Window().Get(s.name).Call("removeItem", k)
}

func (s *jsStorage) Clear() {
	s.mutex.Lock()
	defer s.mutex.Unlock()

	Window().Get(s.name).Call("clear")
}

func encrypt(v []byte, key []byte) ([]byte, error) {
	c, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}

	gcm, err := cipher.NewGCM(c)
	if err != nil {
		return nil, err
	}

	nonce := make([]byte, gcm.NonceSize())
	if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
		return nil, err
	}

	return gcm.Seal(nonce, nonce, v, nil), nil
}

func decrypt(v []byte, key []byte) ([]byte, error) {
	c, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}

	gcm, err := cipher.NewGCM(c)
	if err != nil {
		return nil, err
	}

	nonceSize := gcm.NonceSize()
	if len(v) < nonceSize {
		return nil, errors.New("ciphertext too short")
	}

	nonce, ciphertext := v[:nonceSize], v[nonceSize:]
	return gcm.Open(nil, nonce, ciphertext, nil)
}
<commit_msg>remove storage encryption (#394)<commit_after>package app

import (
	"encoding/json"
	"sync"
)

type jsStorage struct {
	name  string
	mutex sync.RWMutex
}

func newJSStorage(name string) *jsStorage {
	return &jsStorage{name: name}
}

func (s *jsStorage) Set(k string, v interface{}) error {
	s.mutex.Lock()
	defer s.mutex.Unlock()

	b, err := json.Marshal(v)
	if err != nil {
		return err
	}

	Window().Get(s.name).Call("setItem", k, btos(b))
	return nil
}

func (s *jsStorage) Get(k string, v interface{}) error {
	s.mutex.RLock()
	defer s.mutex.RUnlock()

	item := Window().Get(s.name).Call("getItem", k)
	if !item.Truthy() {
		return nil
	}

	return json.Unmarshal(stob(item.String()), v)
}

func (s *jsStorage) Del(k string) {
	s.mutex.Lock()
	defer s.mutex.Unlock()

	Window().Get(s.name).Call("removeItem", k)
}

func (s *jsStorage) Clear() {
	s.mutex.Lock()
	defer s.mutex.Unlock()

	Window().Get(s.name).Call("clear")
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors.

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

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

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

package server

import (
	"fmt"
	"io"
	"net"

	"github.com/spf13/cobra"

	utilerrors "k8s.io/apimachinery/pkg/util/errors"
	genericapiserver "k8s.io/apiserver/pkg/server"
	genericoptions "k8s.io/apiserver/pkg/server/options"
	"k8s.io/sample-apiserver/pkg/admission/plugin/banflunder"
	"k8s.io/sample-apiserver/pkg/admission/wardleinitializer"
	"k8s.io/sample-apiserver/pkg/apis/wardle/v1alpha1"
	"k8s.io/sample-apiserver/pkg/apiserver"
	clientset "k8s.io/sample-apiserver/pkg/client/clientset/internalversion"
	informers "k8s.io/sample-apiserver/pkg/client/informers/internalversion"
)

const defaultEtcdPathPrefix = "/registry/wardle.kubernetes.io"

type WardleServerOptions struct {
	RecommendedOptions *genericoptions.RecommendedOptions
	Admission          *genericoptions.AdmissionOptions

	StdOut io.Writer
	StdErr io.Writer
}

func NewWardleServerOptions(out, errOut io.Writer) *WardleServerOptions {
	o := &WardleServerOptions{
		RecommendedOptions: genericoptions.NewRecommendedOptions(defaultEtcdPathPrefix, apiserver.Codecs.LegacyCodec(v1alpha1.SchemeGroupVersion)),
		Admission:          genericoptions.NewAdmissionOptions(),

		StdOut: out,
		StdErr: errOut,
	}

	return o
}

// NewCommandStartMaster provides a CLI handler for 'start master' command
func NewCommandStartWardleServer(out, errOut io.Writer, stopCh <-chan struct{}) *cobra.Command {
	o := NewWardleServerOptions(out, errOut)

	cmd := &cobra.Command{
		Short: "Launch a wardle API server",
		Long:  "Launch a wardle API server",
		RunE: func(c *cobra.Command, args []string) error {
			if err := o.Complete(); err != nil {
				return err
			}
			if err := o.Validate(args); err != nil {
				return err
			}
			if err := o.RunWardleServer(stopCh); err != nil {
				return err
			}
			return nil
		},
	}

	flags := cmd.Flags()
	o.RecommendedOptions.AddFlags(flags)
	o.Admission.AddFlags(flags)

	return cmd
}

func (o WardleServerOptions) Validate(args []string) error {
	errors := []error{}
	errors = append(errors, o.RecommendedOptions.Validate()...)
	errors = append(errors, o.Admission.Validate()...)
	return utilerrors.NewAggregate(errors)
}

func (o *WardleServerOptions) Complete() error {
	return nil
}

func (o WardleServerOptions) Config() (*apiserver.Config, error) {
	// register admission plugins
	banflunder.Register(o.Admission.Plugins)

	// TODO have a "real" external address
	if err := o.RecommendedOptions.SecureServing.MaybeDefaultWithSelfSignedCerts("localhost", nil, []net.IP{net.ParseIP("127.0.0.1")}); err != nil {
		return nil, fmt.Errorf("error creating self-signed certificates: %v", err)
	}

	serverConfig := genericapiserver.NewRecommendedConfig(apiserver.Codecs)
	if err := o.RecommendedOptions.ApplyTo(serverConfig); err != nil {
		return nil, err
	}

	client, err := clientset.NewForConfig(serverConfig.LoopbackClientConfig)
	if err != nil {
		return nil, err
	}
	informerFactory := informers.NewSharedInformerFactory(client, serverConfig.LoopbackClientConfig.Timeout)
	admissionInitializer, err := wardleinitializer.New(informerFactory)
	if err != nil {
		return nil, err
	}

	if err := o.Admission.ApplyTo(&serverConfig.Config, serverConfig.SharedInformerFactory, nil, nil, serverConfig.ClientConfig, admissionInitializer); err != nil {
		return nil, err
	}

	config := &apiserver.Config{
		GenericConfig: serverConfig,
		ExtraConfig:   apiserver.ExtraConfig{},
	}
	return config, nil
}

func (o WardleServerOptions) RunWardleServer(stopCh <-chan struct{}) error {
	config, err := o.Config()
	if err != nil {
		return err
	}

	server, err := config.Complete().New()
	if err != nil {
		return err
	}

	server.GenericAPIServer.AddPostStartHook("start-sample-server-informers", func(context genericapiserver.PostStartHookContext) error {
		config.GenericConfig.SharedInformerFactory.Start(context.StopCh)
		return nil
	})

	return server.GenericAPIServer.PrepareRun().Run(stopCh)
}
<commit_msg>removes k8s.io/kubernetes/pkg/api dependency from the webhook plugin.<commit_after>/*
Copyright 2016 The Kubernetes Authors.

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

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

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

package server

import (
	"fmt"
	"io"
	"net"

	"github.com/spf13/cobra"

	utilerrors "k8s.io/apimachinery/pkg/util/errors"
	genericapiserver "k8s.io/apiserver/pkg/server"
	genericoptions "k8s.io/apiserver/pkg/server/options"
	"k8s.io/sample-apiserver/pkg/admission/plugin/banflunder"
	"k8s.io/sample-apiserver/pkg/admission/wardleinitializer"
	"k8s.io/sample-apiserver/pkg/apis/wardle/v1alpha1"
	"k8s.io/sample-apiserver/pkg/apiserver"
	clientset "k8s.io/sample-apiserver/pkg/client/clientset/internalversion"
	informers "k8s.io/sample-apiserver/pkg/client/informers/internalversion"
)

const defaultEtcdPathPrefix = "/registry/wardle.kubernetes.io"

type WardleServerOptions struct {
	RecommendedOptions *genericoptions.RecommendedOptions
	Admission          *genericoptions.AdmissionOptions

	StdOut io.Writer
	StdErr io.Writer
}

func NewWardleServerOptions(out, errOut io.Writer) *WardleServerOptions {
	o := &WardleServerOptions{
		RecommendedOptions: genericoptions.NewRecommendedOptions(defaultEtcdPathPrefix, apiserver.Codecs.LegacyCodec(v1alpha1.SchemeGroupVersion)),
		Admission:          genericoptions.NewAdmissionOptions(),

		StdOut: out,
		StdErr: errOut,
	}

	return o
}

// NewCommandStartMaster provides a CLI handler for 'start master' command
func NewCommandStartWardleServer(out, errOut io.Writer, stopCh <-chan struct{}) *cobra.Command {
	o := NewWardleServerOptions(out, errOut)

	cmd := &cobra.Command{
		Short: "Launch a wardle API server",
		Long:  "Launch a wardle API server",
		RunE: func(c *cobra.Command, args []string) error {
			if err := o.Complete(); err != nil {
				return err
			}
			if err := o.Validate(args); err != nil {
				return err
			}
			if err := o.RunWardleServer(stopCh); err != nil {
				return err
			}
			return nil
		},
	}

	flags := cmd.Flags()
	o.RecommendedOptions.AddFlags(flags)
	o.Admission.AddFlags(flags)

	return cmd
}

func (o WardleServerOptions) Validate(args []string) error {
	errors := []error{}
	errors = append(errors, o.RecommendedOptions.Validate()...)
	errors = append(errors, o.Admission.Validate()...)
	return utilerrors.NewAggregate(errors)
}

func (o *WardleServerOptions) Complete() error {
	return nil
}

func (o WardleServerOptions) Config() (*apiserver.Config, error) {
	// register admission plugins
	banflunder.Register(o.Admission.Plugins)

	// TODO have a "real" external address
	if err := o.RecommendedOptions.SecureServing.MaybeDefaultWithSelfSignedCerts("localhost", nil, []net.IP{net.ParseIP("127.0.0.1")}); err != nil {
		return nil, fmt.Errorf("error creating self-signed certificates: %v", err)
	}

	serverConfig := genericapiserver.NewRecommendedConfig(apiserver.Codecs)
	if err := o.RecommendedOptions.ApplyTo(serverConfig); err != nil {
		return nil, err
	}

	client, err := clientset.NewForConfig(serverConfig.LoopbackClientConfig)
	if err != nil {
		return nil, err
	}
	informerFactory := informers.NewSharedInformerFactory(client, serverConfig.LoopbackClientConfig.Timeout)
	admissionInitializer, err := wardleinitializer.New(informerFactory)
	if err != nil {
		return nil, err
	}

	if err := o.Admission.ApplyTo(&serverConfig.Config, serverConfig.SharedInformerFactory, nil, nil, serverConfig.ClientConfig, apiserver.Scheme, admissionInitializer); err != nil {
		return nil, err
	}

	config := &apiserver.Config{
		GenericConfig: serverConfig,
		ExtraConfig:   apiserver.ExtraConfig{},
	}
	return config, nil
}

func (o WardleServerOptions) RunWardleServer(stopCh <-chan struct{}) error {
	config, err := o.Config()
	if err != nil {
		return err
	}

	server, err := config.Complete().New()
	if err != nil {
		return err
	}

	server.GenericAPIServer.AddPostStartHook("start-sample-server-informers", func(context genericapiserver.PostStartHookContext) error {
		config.GenericConfig.SharedInformerFactory.Start(context.StopCh)
		return nil
	})

	return server.GenericAPIServer.PrepareRun().Run(stopCh)
}
<|endoftext|>


<commit_before>package controller

import (
	"math"
	"strconv"
	"time"

	"github.com/tidwall/gjson"
	"github.com/tidwall/tile38/pkg/geojson"
	"github.com/tidwall/tile38/pkg/glob"
	"github.com/tidwall/tile38/pkg/server"
)

// FenceMatch executes a fence match returns back json messages for fence detection.
func FenceMatch(hookName string, sw *scanWriter, fence *liveFenceSwitches, metas []FenceMeta, details *commandDetailsT) [][]byte {
	msgs := fenceMatch(hookName, sw, fence, metas, details)
	if len(fence.accept) == 0 {
		return msgs
	}
	nmsgs := make([][]byte, 0, len(msgs))
	for _, msg := range msgs {
		if fence.accept[gjson.GetBytes(msg, "command").String()] {
			nmsgs = append(nmsgs, msg)
		}
	}
	return nmsgs
}
func appendJSONTimeFormat(b []byte, t time.Time) []byte {
	b = append(b, '"')
	b = t.AppendFormat(b, "2006-01-02T15:04:05.999999999Z07:00")
	b = append(b, '"')
	return b
}
func jsonTimeFormat(t time.Time) string {
	var b []byte
	b = appendJSONTimeFormat(b, t)
	return string(b)
}
func appendHookDetails(b []byte, hookName string, metas []FenceMeta) []byte {
	if len(hookName) > 0 {
		b = append(b, `,"hook":`...)
		b = appendJSONString(b, hookName)
	}
	if len(metas) > 0 {
		b = append(b, `,"meta":{`...)
		for i, meta := range metas {
			if i > 0 {
				b = append(b, ',')
			}
			b = appendJSONString(b, meta.Name)
			b = append(b, ':')
			b = appendJSONString(b, meta.Value)
		}
		b = append(b, '}')
	}
	return b
}
func hookJSONString(hookName string, metas []FenceMeta) string {
	return string(appendHookDetails(nil, hookName, metas))
}
func fenceMatch(hookName string, sw *scanWriter, fence *liveFenceSwitches, metas []FenceMeta, details *commandDetailsT) [][]byte {
	if details.command == "drop" {
		return [][]byte{[]byte(`{"command":"drop"` + hookJSONString(hookName, metas) + `,"time":` + jsonTimeFormat(details.timestamp) + `}`)}
	}
	if len(fence.glob) > 0 && !(len(fence.glob) == 1 && fence.glob[0] == '*') {
		match, _ := glob.Match(fence.glob, details.id)
		if !match {
			return nil
		}
	}
	if details.obj == nil || !details.obj.IsGeometry() {
		return nil
	}
	if details.command == "fset" {
		sw.mu.Lock()
		nofields := sw.nofields
		sw.mu.Unlock()
		if nofields {
			return nil
		}
	}
	if details.command == "del" {
		return [][]byte{[]byte(`{"command":"del"` + hookJSONString(hookName, metas) + `,"id":` + jsonString(details.id) + `,"time":` + jsonTimeFormat(details.timestamp) + `}`)}
	}
	var roamkeys, roamids []string
	var roammeters []float64
	var detect = "outside"
	if fence != nil {
		if fence.roam.on {
			if details.command == "set" {
				roamkeys, roamids, roammeters = fenceMatchRoam(sw.c, fence, details.key, details.id, details.obj)
			}
			if len(roamids) == 0 || len(roamids) != len(roamkeys) {
				return nil
			}
			detect = "roam"
		} else {
			// not using roaming
			match1 := fenceMatchObject(fence, details.oldObj)
			match2 := fenceMatchObject(fence, details.obj)
			if match1 && match2 {
				detect = "inside"
			} else if match1 && !match2 {
				detect = "exit"
			} else if !match1 && match2 {
				detect = "enter"
				if details.command == "fset" {
					detect = "inside"
				}
			} else {
				if details.command != "fset" {
					// Maybe the old object and new object create a line that crosses the fence.
					// Must detect for that possibility.
					if details.oldObj != nil {
						ls := geojson.LineString{
							Coordinates: []geojson.Position{
								details.oldObj.CalculatedPoint(),
								details.obj.CalculatedPoint(),
							},
						}
						temp := false
						if fence.cmd == "within" {
							// because we are testing if the line croses the area we need to use
							// "intersects" instead of "within".
							fence.cmd = "intersects"
							temp = true
						}
						if fenceMatchObject(fence, ls) {
							detect = "cross"
						}
						if temp {
							fence.cmd = "within"
						}
					}
				}
			}
		}
	}

	if details.fmap == nil {
		return nil
	}
	for {
		if fence.detect != nil && !fence.detect[detect] {
			if detect == "enter" {
				detect = "inside"
				continue
			}
			if detect == "exit" {
				detect = "outside"
				continue
			}
			return nil
		}
		break
	}
	sw.mu.Lock()
	var distance float64
	if fence.distance {
		distance = details.obj.CalculatedPoint().DistanceTo(geojson.Position{X: fence.lon, Y: fence.lat, Z: 0})
	}
	sw.fmap = details.fmap
	sw.fullFields = true
	sw.msg.OutputType = server.JSON
	sw.writeObject(ScanWriterParams{
		id:       details.id,
		o:        details.obj,
		fields:   details.fields,
		noLock:   true,
		distance: distance,
	})

	if sw.wr.Len() == 0 {
		sw.mu.Unlock()
		return nil
	}

	res := make([]byte, sw.wr.Len())
	copy(res, sw.wr.Bytes())
	sw.wr.Reset()
	if len(res) > 0 && res[0] == ',' {
		res = res[1:]
	}
	if sw.output == outputIDs {
		res = []byte(`{"id":` + string(res) + `}`)
	}
	sw.mu.Unlock()

	if fence.groups == nil {
		fence.groups = make(map[string]string)
	}
	groupkey := details.key + ":" + details.id
	var group string
	var ok bool
	if detect == "enter" {
		group = bsonID()
		fence.groups[groupkey] = group
	} else if detect == "cross" {
		group = bsonID()
		delete(fence.groups, groupkey)
	} else {
		group, ok = fence.groups[groupkey]
		if !ok {
			group = bsonID()
			fence.groups[groupkey] = group
		}
	}

	var msgs [][]byte
	if fence.detect == nil || fence.detect[detect] {
		if len(res) > 0 && res[0] == '{' {
			msgs = append(msgs, makemsg(details.command, group, detect, hookName, metas, details.key, details.timestamp, res[1:]))
		} else {
			msgs = append(msgs, res)
		}
	}
	switch detect {
	case "enter":
		if fence.detect == nil || fence.detect["inside"] {
			msgs = append(msgs, makemsg(details.command, group, "inside", hookName, metas, details.key, details.timestamp, res[1:]))
		}
	case "exit", "cross":
		if fence.detect == nil || fence.detect["outside"] {
			msgs = append(msgs, makemsg(details.command, group, "outside", hookName, metas, details.key, details.timestamp, res[1:]))
		}
	case "roam":
		if len(msgs) > 0 {
			var nmsgs [][]byte
			msg := msgs[0][:len(msgs[0])-1]
			for i, id := range roamids {

				nmsg := append([]byte(nil), msg...)
				nmsg = append(nmsg, `,"nearby":{"key":`...)
				nmsg = appendJSONString(nmsg, roamkeys[i])
				nmsg = append(nmsg, `,"id":`...)
				nmsg = appendJSONString(nmsg, id)
				nmsg = append(nmsg, `,"meters":`...)
				nmsg = append(nmsg, strconv.FormatFloat(roammeters[i], 'f', -1, 64)...)

				if fence.roam.scan != "" {
					nmsg = append(nmsg, `,"scan":[`...)

					func() {
						sw.c.mu.Lock()
						defer sw.c.mu.Unlock()
						col := sw.c.getCol(roamkeys[i])
						if col != nil {
							obj, _, ok := col.Get(id)
							if ok {
								nmsg = append(nmsg, `{"id":`+jsonString(id)+`,"self":true,"object":`+obj.JSON()+`}`...)
							}
							pattern := id + fence.roam.scan
							iterator := func(oid string, o geojson.Object, fields []float64) bool {
								if oid == id {
									return true
								}
								if matched, _ := glob.Match(pattern, oid); matched {
									nmsg = append(nmsg, `,{"id":`+jsonString(oid)+`,"object":`+o.JSON()+`}`...)
								}
								return true
							}
							g := glob.Parse(pattern, false)
							if g.Limits[0] == "" && g.Limits[1] == "" {
								col.Scan(false, iterator)
							} else {
								col.ScanRange(g.Limits[0], g.Limits[1], false, iterator)
							}
						}
					}()
					nmsg = append(nmsg, ']')
				}

				nmsg = append(nmsg, '}')
				nmsg = append(nmsg, '}')
				nmsgs = append(nmsgs, nmsg)
			}
			msgs = nmsgs
		}
	}
	return msgs
}

func makemsg(command, group, detect, hookName string, metas []FenceMeta, key string, t time.Time, tail []byte) []byte {
	var buf []byte
	buf = append(append(buf, `{"command":"`...), command...)
	buf = append(append(buf, `","group":"`...), group...)
	buf = append(append(buf, `","detect":"`...), detect...)
	buf = append(buf, '"')
	buf = appendHookDetails(buf, hookName, metas)
	buf = appendJSONString(append(buf, `,"key":`...), key)
	buf = appendJSONTimeFormat(append(buf, `,"time":`...), t)
	buf = append(append(buf, ','), tail...)
	return buf
}

func fenceMatchObject(fence *liveFenceSwitches, obj geojson.Object) bool {
	if obj == nil {
		return false
	}
	if fence.roam.on {
		// we need to check this object against
		return false
	}

	if fence.cmd == "nearby" {
		return obj.Nearby(geojson.Position{X: fence.lon, Y: fence.lat, Z: 0}, fence.meters)
	}
	if fence.cmd == "within" {
		if fence.o != nil {
			return obj.Within(fence.o)
		}
		return obj.WithinBBox(geojson.BBox{
			Min: geojson.Position{X: fence.minLon, Y: fence.minLat, Z: 0},
			Max: geojson.Position{X: fence.maxLon, Y: fence.maxLat, Z: 0},
		})
	}
	if fence.cmd == "intersects" {
		if fence.o != nil {
			return obj.Intersects(fence.o)
		}
		return obj.IntersectsBBox(geojson.BBox{
			Min: geojson.Position{X: fence.minLon, Y: fence.minLat, Z: 0},
			Max: geojson.Position{X: fence.maxLon, Y: fence.maxLat, Z: 0},
		})
	}
	return false
}

func fenceMatchRoam(c *Controller, fence *liveFenceSwitches, tkey, tid string, obj geojson.Object) (keys, ids []string, meterss []float64) {
	col := c.getCol(fence.roam.key)
	if col == nil {
		return
	}
	p := obj.CalculatedPoint()
	col.Nearby(0, p.Y, p.X, fence.roam.meters, math.Inf(-1), math.Inf(+1),
		func(id string, obj geojson.Object, fields []float64) bool {
			var match bool
			if id == tid {
				return true // skip self
			}
			if fence.roam.pattern {
				match, _ = glob.Match(fence.roam.id, id)
			} else {
				match = fence.roam.id == id
			}
			if match {
				keys = append(keys, fence.roam.key)
				ids = append(ids, id)
				meterss = append(meterss, obj.CalculatedPoint().DistanceTo(p))
			}
			return true
		},
	)
	return
}
<commit_msg>Fix data race<commit_after>package controller

import (
	"math"
	"strconv"
	"time"

	"github.com/tidwall/gjson"
	"github.com/tidwall/tile38/pkg/geojson"
	"github.com/tidwall/tile38/pkg/glob"
	"github.com/tidwall/tile38/pkg/server"
)

// FenceMatch executes a fence match returns back json messages for fence detection.
func FenceMatch(hookName string, sw *scanWriter, fence *liveFenceSwitches, metas []FenceMeta, details *commandDetailsT) [][]byte {
	msgs := fenceMatch(hookName, sw, fence, metas, details)
	if len(fence.accept) == 0 {
		return msgs
	}
	nmsgs := make([][]byte, 0, len(msgs))
	for _, msg := range msgs {
		if fence.accept[gjson.GetBytes(msg, "command").String()] {
			nmsgs = append(nmsgs, msg)
		}
	}
	return nmsgs
}
func appendJSONTimeFormat(b []byte, t time.Time) []byte {
	b = append(b, '"')
	b = t.AppendFormat(b, "2006-01-02T15:04:05.999999999Z07:00")
	b = append(b, '"')
	return b
}
func jsonTimeFormat(t time.Time) string {
	var b []byte
	b = appendJSONTimeFormat(b, t)
	return string(b)
}
func appendHookDetails(b []byte, hookName string, metas []FenceMeta) []byte {
	if len(hookName) > 0 {
		b = append(b, `,"hook":`...)
		b = appendJSONString(b, hookName)
	}
	if len(metas) > 0 {
		b = append(b, `,"meta":{`...)
		for i, meta := range metas {
			if i > 0 {
				b = append(b, ',')
			}
			b = appendJSONString(b, meta.Name)
			b = append(b, ':')
			b = appendJSONString(b, meta.Value)
		}
		b = append(b, '}')
	}
	return b
}
func hookJSONString(hookName string, metas []FenceMeta) string {
	return string(appendHookDetails(nil, hookName, metas))
}
func fenceMatch(hookName string, sw *scanWriter, fence *liveFenceSwitches, metas []FenceMeta, details *commandDetailsT) [][]byte {
	if details.command == "drop" {
		return [][]byte{[]byte(`{"command":"drop"` + hookJSONString(hookName, metas) + `,"time":` + jsonTimeFormat(details.timestamp) + `}`)}
	}
	if len(fence.glob) > 0 && !(len(fence.glob) == 1 && fence.glob[0] == '*') {
		match, _ := glob.Match(fence.glob, details.id)
		if !match {
			return nil
		}
	}
	if details.obj == nil || !details.obj.IsGeometry() {
		return nil
	}
	if details.command == "fset" {
		sw.mu.Lock()
		nofields := sw.nofields
		sw.mu.Unlock()
		if nofields {
			return nil
		}
	}
	if details.command == "del" {
		return [][]byte{[]byte(`{"command":"del"` + hookJSONString(hookName, metas) + `,"id":` + jsonString(details.id) + `,"time":` + jsonTimeFormat(details.timestamp) + `}`)}
	}
	var roamkeys, roamids []string
	var roammeters []float64
	var detect = "outside"
	if fence != nil {
		if fence.roam.on {
			if details.command == "set" {
				roamkeys, roamids, roammeters = fenceMatchRoam(sw.c, fence, details.key, details.id, details.obj)
			}
			if len(roamids) == 0 || len(roamids) != len(roamkeys) {
				return nil
			}
			detect = "roam"
		} else {
			// not using roaming
			match1 := fenceMatchObject(fence, details.oldObj)
			match2 := fenceMatchObject(fence, details.obj)
			if match1 && match2 {
				detect = "inside"
			} else if match1 && !match2 {
				detect = "exit"
			} else if !match1 && match2 {
				detect = "enter"
				if details.command == "fset" {
					detect = "inside"
				}
			} else {
				if details.command != "fset" {
					// Maybe the old object and new object create a line that crosses the fence.
					// Must detect for that possibility.
					if details.oldObj != nil {
						ls := geojson.LineString{
							Coordinates: []geojson.Position{
								details.oldObj.CalculatedPoint(),
								details.obj.CalculatedPoint(),
							},
						}
						temp := false
						if fence.cmd == "within" {
							// because we are testing if the line croses the area we need to use
							// "intersects" instead of "within".
							fence.cmd = "intersects"
							temp = true
						}
						if fenceMatchObject(fence, ls) {
							detect = "cross"
						}
						if temp {
							fence.cmd = "within"
						}
					}
				}
			}
		}
	}

	if details.fmap == nil {
		return nil
	}
	for {
		if fence.detect != nil && !fence.detect[detect] {
			if detect == "enter" {
				detect = "inside"
				continue
			}
			if detect == "exit" {
				detect = "outside"
				continue
			}
			return nil
		}
		break
	}
	sw.mu.Lock()
	var distance float64
	if fence.distance {
		distance = details.obj.CalculatedPoint().DistanceTo(geojson.Position{X: fence.lon, Y: fence.lat, Z: 0})
	}
	sw.fmap = details.fmap
	sw.fullFields = true
	sw.msg.OutputType = server.JSON
	sw.writeObject(ScanWriterParams{
		id:       details.id,
		o:        details.obj,
		fields:   details.fields,
		noLock:   true,
		distance: distance,
	})

	if sw.wr.Len() == 0 {
		sw.mu.Unlock()
		return nil
	}

	res := make([]byte, sw.wr.Len())
	copy(res, sw.wr.Bytes())
	sw.wr.Reset()
	if len(res) > 0 && res[0] == ',' {
		res = res[1:]
	}
	if sw.output == outputIDs {
		res = []byte(`{"id":` + string(res) + `}`)
	}
	sw.mu.Unlock()

	if fence.groups == nil {
		fence.groups = make(map[string]string)
	}
	groupkey := details.key + ":" + details.id
	var group string
	var ok bool
	if detect == "enter" {
		group = bsonID()
		fence.groups[groupkey] = group
	} else if detect == "cross" {
		group = bsonID()
		delete(fence.groups, groupkey)
	} else {
		group, ok = fence.groups[groupkey]
		if !ok {
			group = bsonID()
			fence.groups[groupkey] = group
		}
	}

	var msgs [][]byte
	if fence.detect == nil || fence.detect[detect] {
		if len(res) > 0 && res[0] == '{' {
			msgs = append(msgs, makemsg(details.command, group, detect, hookName, metas, details.key, details.timestamp, res[1:]))
		} else {
			msgs = append(msgs, res)
		}
	}
	switch detect {
	case "enter":
		if fence.detect == nil || fence.detect["inside"] {
			msgs = append(msgs, makemsg(details.command, group, "inside", hookName, metas, details.key, details.timestamp, res[1:]))
		}
	case "exit", "cross":
		if fence.detect == nil || fence.detect["outside"] {
			msgs = append(msgs, makemsg(details.command, group, "outside", hookName, metas, details.key, details.timestamp, res[1:]))
		}
	case "roam":
		if len(msgs) > 0 {
			var nmsgs [][]byte
			msg := msgs[0][:len(msgs[0])-1]
			for i, id := range roamids {

				nmsg := append([]byte(nil), msg...)
				nmsg = append(nmsg, `,"nearby":{"key":`...)
				nmsg = appendJSONString(nmsg, roamkeys[i])
				nmsg = append(nmsg, `,"id":`...)
				nmsg = appendJSONString(nmsg, id)
				nmsg = append(nmsg, `,"meters":`...)
				nmsg = append(nmsg, strconv.FormatFloat(roammeters[i], 'f', -1, 64)...)

				if fence.roam.scan != "" {
					nmsg = append(nmsg, `,"scan":[`...)

					func() {
						sw.c.mu.Lock()
						defer sw.c.mu.Unlock()
						col := sw.c.getCol(roamkeys[i])
						if col != nil {
							obj, _, ok := col.Get(id)
							if ok {
								nmsg = append(nmsg, `{"id":`+jsonString(id)+`,"self":true,"object":`+obj.JSON()+`}`...)
							}
							pattern := id + fence.roam.scan
							iterator := func(oid string, o geojson.Object, fields []float64) bool {
								if oid == id {
									return true
								}
								if matched, _ := glob.Match(pattern, oid); matched {
									nmsg = append(nmsg, `,{"id":`+jsonString(oid)+`,"object":`+o.JSON()+`}`...)
								}
								return true
							}
							g := glob.Parse(pattern, false)
							if g.Limits[0] == "" && g.Limits[1] == "" {
								col.Scan(false, iterator)
							} else {
								col.ScanRange(g.Limits[0], g.Limits[1], false, iterator)
							}
						}
					}()
					nmsg = append(nmsg, ']')
				}

				nmsg = append(nmsg, '}')
				nmsg = append(nmsg, '}')
				nmsgs = append(nmsgs, nmsg)
			}
			msgs = nmsgs
		}
	}
	return msgs
}

func makemsg(command, group, detect, hookName string, metas []FenceMeta, key string, t time.Time, tail []byte) []byte {
	var buf []byte
	buf = append(append(buf, `{"command":"`...), command...)
	buf = append(append(buf, `","group":"`...), group...)
	buf = append(append(buf, `","detect":"`...), detect...)
	buf = append(buf, '"')
	buf = appendHookDetails(buf, hookName, metas)
	buf = appendJSONString(append(buf, `,"key":`...), key)
	buf = appendJSONTimeFormat(append(buf, `,"time":`...), t)
	buf = append(append(buf, ','), tail...)
	return buf
}

func fenceMatchObject(fence *liveFenceSwitches, obj geojson.Object) bool {
	if obj == nil {
		return false
	}
	if fence.roam.on {
		// we need to check this object against
		return false
	}

	if fence.cmd == "nearby" {
		return obj.Nearby(geojson.Position{X: fence.lon, Y: fence.lat, Z: 0}, fence.meters)
	}
	if fence.cmd == "within" {
		if fence.o != nil {
			return obj.Within(fence.o)
		}
		return obj.WithinBBox(geojson.BBox{
			Min: geojson.Position{X: fence.minLon, Y: fence.minLat, Z: 0},
			Max: geojson.Position{X: fence.maxLon, Y: fence.maxLat, Z: 0},
		})
	}
	if fence.cmd == "intersects" {
		if fence.o != nil {
			return obj.Intersects(fence.o)
		}
		return obj.IntersectsBBox(geojson.BBox{
			Min: geojson.Position{X: fence.minLon, Y: fence.minLat, Z: 0},
			Max: geojson.Position{X: fence.maxLon, Y: fence.maxLat, Z: 0},
		})
	}
	return false
}

func fenceMatchRoam(c *Controller, fence *liveFenceSwitches, tkey, tid string, obj geojson.Object) (keys, ids []string, meterss []float64) {
	c.mu.RLock()
	defer c.mu.RUnlock()
	col := c.getCol(fence.roam.key)
	if col == nil {
		return
	}
	p := obj.CalculatedPoint()
	col.Nearby(0, p.Y, p.X, fence.roam.meters, math.Inf(-1), math.Inf(+1),
		func(id string, obj geojson.Object, fields []float64) bool {
			var match bool
			if id == tid {
				return true // skip self
			}
			if fence.roam.pattern {
				match, _ = glob.Match(fence.roam.id, id)
			} else {
				match = fence.roam.id == id
			}
			if match {
				keys = append(keys, fence.roam.key)
				ids = append(ids, id)
				meterss = append(meterss, obj.CalculatedPoint().DistanceTo(p))
			}
			return true
		},
	)
	return
}
<|endoftext|>


<commit_before>package etcdutil

import (
	"math"
	"path"
	"strconv"
	"time"

	"github.com/coreos/go-etcd/etcd"
)

// heartbeat to etcd cluster until stop
func Heartbeat(client *etcd.Client, name string, taskID uint64, interval time.Duration, stop chan struct{}) error {
	for {
		_, err := client.Set(HealthyPath(name, taskID), "health", computeTTL(interval))
		if err != nil {
			return err
		}
		select {
		case <-time.After(interval):
		case <-stop:
			return nil
		}
	}
}

// detect failure of the given taskID
func DetectFailure(client *etcd.Client, name string, taskID uint64, stop chan bool) (uint64, error) {
	key := HealthyPath(name, taskID)
	resp, err := client.Get(key, false, false)
	if err != nil {
		// TODO: should check "key not found"
		return taskID, nil
	}
	waitIndex := resp.EtcdIndex + 1
	for {
		resp, err = client.Watch(key, waitIndex, false, nil, stop)
		if err != nil {
			// on client closing
			return 0, err
		}
		if resp.Action == "delete" || resp.Action == "expire" {
			return taskID, nil
		}
		waitIndex = resp.EtcdIndex + 1
	}
}

// report failure to etcd cluster
// If a framework detects a failure, it tries to report failure to /failedTasks/{taskID}
func ReportFailure(client *etcd.Client, name string, taskID uint64) {
	client.Set(FailedTaskPath(name, taskID), "failed", 0)
}

// WaitFailure blocks until it gets a hint of taks failure
func WaitFailure(client *etcd.Client, name string) (uint64, error) {
	resp, err := client.Watch(FailedTaskDir(name), 0, true, nil, nil)
	if err != nil {
		return 0, err
	}
	idStr := path.Base(resp.Node.Key)
	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil {
		return 0, err
	}
	return id, nil
}

func computeTTL(interval time.Duration) uint64 {
	return uint64(math.Min(5*float64(interval/time.Second), 1))
}
<commit_msg>panic on unhandled error<commit_after>package etcdutil

import (
	"math"
	"path"
	"strconv"
	"time"

	"github.com/coreos/go-etcd/etcd"
)

// heartbeat to etcd cluster until stop
func Heartbeat(client *etcd.Client, name string, taskID uint64, interval time.Duration, stop chan struct{}) error {
	for {
		_, err := client.Set(HealthyPath(name, taskID), "health", computeTTL(interval))
		if err != nil {
			return err
		}
		select {
		case <-time.After(interval):
		case <-stop:
			return nil
		}
	}
}

// detect failure of the given taskID
func DetectFailure(client *etcd.Client, name string, taskID uint64, stop chan bool) (uint64, error) {
	key := HealthyPath(name, taskID)
	resp, err := client.Get(key, false, false)
	if err != nil {
		// TODO: should check "key not found"
		return taskID, nil
	}
	waitIndex := resp.EtcdIndex + 1
	for {
		resp, err = client.Watch(key, waitIndex, false, nil, stop)
		if err != nil {
			// on client closing
			return 0, err
		}
		if resp.Action == "delete" || resp.Action == "expire" {
			return taskID, nil
		}
		waitIndex = resp.EtcdIndex + 1
	}
}

// report failure to etcd cluster
// If a framework detects a failure, it tries to report failure to /failedTasks/{taskID}
func ReportFailure(client *etcd.Client, name string, taskID uint64) {
	_, err := client.Set(FailedTaskPath(name, taskID), "failed", 0)
	if err != nil {
		panic("unimplemented")
	}
}

// WaitFailure blocks until it gets a hint of taks failure
func WaitFailure(client *etcd.Client, name string) (uint64, error) {
	resp, err := client.Watch(FailedTaskDir(name), 0, true, nil, nil)
	if err != nil {
		return 0, err
	}
	idStr := path.Base(resp.Node.Key)
	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil {
		return 0, err
	}
	return id, nil
}

func computeTTL(interval time.Duration) uint64 {
	return uint64(math.Min(5*float64(interval/time.Second), 1))
}
<|endoftext|>


<commit_before>package exchange

import (
	"github.com/gobwas/glob"

	"nimona.io/pkg/crypto"
	"nimona.io/pkg/errors"
)

func FilterBySender(keys ...crypto.PublicKey) EnvelopeFilter {
	return func(e *Envelope) bool {
		for _, key := range keys {
			if e.Sender.Equals(key) {
				return true
			}
		}
		return false
	}
}

func FilterByObjectType(typePatterns ...string) EnvelopeFilter {
	patterns := make([]glob.Glob, len(typePatterns))
	for i, typePattern := range typePatterns {
		g, err := glob.Compile(typePattern, '.', '/', '#')
		if err != nil {
			panic(errors.Wrap(err, errors.New("invalid pattern")))
		}
		patterns[i] = g
	}
	return func(e *Envelope) bool {
		for _, pattern := range patterns {
			if pattern.Match(e.Payload.GetType()) {
				return true
			}
		}
		return false
	}
}
<commit_msg>chore(exchange): add FilterByObjectHash<commit_after>package exchange

import (
	"github.com/gobwas/glob"

	"nimona.io/pkg/crypto"
	"nimona.io/pkg/errors"
	"nimona.io/pkg/object"
)

func FilterBySender(keys ...crypto.PublicKey) EnvelopeFilter {
	return func(e *Envelope) bool {
		for _, key := range keys {
			if e.Sender.Equals(key) {
				return true
			}
		}
		return false
	}
}

func FilterByObjectType(typePatterns ...string) EnvelopeFilter {
	patterns := make([]glob.Glob, len(typePatterns))
	for i, typePattern := range typePatterns {
		g, err := glob.Compile(typePattern, '.', '/', '#')
		if err != nil {
			panic(errors.Wrap(err, errors.New("invalid pattern")))
		}
		patterns[i] = g
	}
	return func(e *Envelope) bool {
		for _, pattern := range patterns {
			if pattern.Match(e.Payload.GetType()) {
				return true
			}
		}
		return false
	}
}

func FilterByObjectHash(objectHashes ...object.Hash) EnvelopeFilter {
	return func(e *Envelope) bool {
		for _, hash := range objectHashes {
			if hash == e.Payload.Hash() {
				return true
			}
		}
		return false
	}
}
<|endoftext|>