<commit_before>// Copyright 2018 The Ebiten 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 shareable

import (
	"fmt"
	"image"
	"image/color"
	"runtime"

	"github.com/hajimehoshi/ebiten/internal/affine"
	"github.com/hajimehoshi/ebiten/internal/graphics"
	"github.com/hajimehoshi/ebiten/internal/opengl"
	"github.com/hajimehoshi/ebiten/internal/packing"
	"github.com/hajimehoshi/ebiten/internal/restorable"
	"github.com/hajimehoshi/ebiten/internal/sync"
)

type backend struct {
	restorable *restorable.Image

	// If page is nil, the backend is not shared.
	page *packing.Page
}

func (b *backend) TryAlloc(width, height int) (*packing.Node, bool) {
	// If the region is allocated without any extention, it's fine.
	if n := b.page.Alloc(width, height); n != nil {
		return n, true
	}

	// Simulate the extending the page and calculate the appropriate page size.
	page := b.page.Clone()
	nExtended := 0
	for {
		if !page.Extend() {
			// The page can't be extended any more. Return as failure.
			return nil, false
		}
		nExtended++
		if n := page.Alloc(width, height); n != nil {
			break
		}
	}

	for i := 0; i < nExtended; i++ {
		b.page.Extend()
	}
	s := b.page.Size()
	newImg := restorable.NewImage(s, s, false)
	oldImg := b.restorable
	w, h := oldImg.Size()
	newImg.DrawImage(oldImg, 0, 0, w, h, nil, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
	oldImg.Dispose()
	b.restorable = newImg

	n := b.page.Alloc(width, height)
	if n == nil {
		panic("not reached")
	}
	return n, true
}

var (
	// backendsM is a mutex for critical sections of the backend and packing.Node objects.
	backendsM sync.Mutex

	// theBackends is a set of actually shared images.
	theBackends = []*backend{}
)

type Image struct {
	width    int
	height   int
	disposed bool

	backend *backend

	// If node is nil, the image is not shared.
	node *packing.Node
}

func (i *Image) ensureNotShared() {
	if i.backend == nil {
		i.allocate(false)
		return
	}

	if i.node == nil {
		return
	}

	x, y, w, h := i.region()
	newImg := restorable.NewImage(w, h, false)
	newImg.DrawImage(i.backend.restorable, x, y, x+w, y+h, nil, nil, opengl.CompositeModeCopy, graphics.FilterNearest)

	i.dispose()
	i.backend = &backend{
		restorable: newImg,
	}
}

func (i *Image) region() (x, y, width, height int) {
	if i.backend == nil {
		panic("not reached")
	}
	if i.node == nil {
		w, h := i.backend.restorable.Size()
		return 0, 0, w, h
	}
	return i.node.Region()
}

func (i *Image) Size() (width, height int) {
	return i.width, i.height
}

func (i *Image) DrawImage(img *Image, sx0, sy0, sx1, sy1 int, geom *affine.GeoM, colorm *affine.ColorM, mode opengl.CompositeMode, filter graphics.Filter) {
	backendsM.Lock()
	defer backendsM.Unlock()

	if img.disposed {
		panic("shareable: the drawing source image must not be disposed")
	}
	if i.disposed {
		panic("shareable: the drawing target image must not be disposed")
	}
	if img.backend == nil {
		img.allocate(true)
	}

	i.ensureNotShared()

	// Compare i and img after ensuring i is not shared, or
	// i and img might share the same texture even though i != img.
	if i.backend.restorable == img.backend.restorable {
		panic("shareable: Image.DrawImage: img must be different from the receiver")
	}

	dx, dy, _, _ := img.region()
	sx0 += dx
	sy0 += dy
	sx1 += dx
	sy1 += dy
	i.backend.restorable.DrawImage(img.backend.restorable, sx0, sy0, sx1, sy1, geom, colorm, mode, filter)
}

func (i *Image) ReplacePixels(p []byte) {
	backendsM.Lock()
	defer backendsM.Unlock()

	if i.disposed {
		panic("shareable: the image must not be disposed")
	}
	if i.backend == nil {
		i.allocate(true)
	}

	x, y, w, h := i.region()
	if l := 4 * w * h; len(p) != l {
		panic(fmt.Sprintf("shareable: len(p) was %d but must be %d", len(p), l))
	}
	i.backend.restorable.ReplacePixels(p, x, y, w, h)
}

func (i *Image) At(x, y int) (color.Color, error) {
	backendsM.Lock()
	defer backendsM.Unlock()

	if i.backend == nil {
		return color.RGBA{}, nil
	}

	ox, oy, w, h := i.region()
	if x < 0 || y < 0 || x >= w || y >= h {
		return color.RGBA{}, nil
	}

	clr, err := i.backend.restorable.At(x+ox, y+oy)
	return clr, err
}

func (i *Image) Dispose() {
	backendsM.Lock()
	defer backendsM.Unlock()
	i.dispose()
}

func (i *Image) dispose() {
	defer func() {
		i.disposed = true
		i.backend = nil
		i.node = nil
		runtime.SetFinalizer(i, nil)
	}()

	if i.disposed {
		return
	}

	if i.backend == nil {
		// Not allocated yet.
		return
	}

	if i.node == nil {
		i.backend.restorable.Dispose()
		return
	}

	i.backend.page.Free(i.node)
	if !i.backend.page.IsEmpty() {
		// As this part can be reused, this should be cleared explicitly.
		x0, y0, x1, y1 := i.region()
		i.backend.restorable.ReplacePixels(nil, x0, y0, x1, y1)
		return
	}

	i.backend.restorable.Dispose()
	index := -1
	for idx, sh := range theBackends {
		if sh == i.backend {
			index = idx
			break
		}
	}
	if index == -1 {
		panic("not reached")
	}
	theBackends = append(theBackends[:index], theBackends[index+1:]...)
}

func (i *Image) IsInvalidated() (bool, error) {
	backendsM.Lock()
	defer backendsM.Unlock()
	v, err := i.backend.restorable.IsInvalidated()
	return v, err
}

func NewImage(width, height int) *Image {
	// Actual allocation is done lazily.
	return &Image{
		width:  width,
		height: height,
	}
}

func (i *Image) allocate(shareable bool) {
	if i.backend != nil {
		panic("not reached")
	}

	const (
		initSize = 1024
		maxSize  = 4096
	)

	if !shareable || i.width > maxSize || i.height > maxSize {
		i.backend = &backend{
			restorable: restorable.NewImage(i.width, i.height, false),
		}
		return
	}

	for _, b := range theBackends {
		if n, ok := b.TryAlloc(i.width, i.height); ok {
			i.backend = b
			i.node = n
			return
		}
	}
	size := initSize
	for i.width > size || i.height > size {
		if size == maxSize {
			panic("not reached")
		}
		size *= 2
	}

	b := &backend{
		restorable: restorable.NewImage(size, size, false),
		page:       packing.NewPage(size, maxSize),
	}
	theBackends = append(theBackends, b)

	n := b.page.Alloc(i.width, i.height)
	if n == nil {
		panic("not reached")
	}
	i.backend = b
	i.node = n
	runtime.SetFinalizer(i, (*Image).Dispose)
	return
}

func NewVolatileImage(width, height int) *Image {
	backendsM.Lock()
	defer backendsM.Unlock()

	r := restorable.NewImage(width, height, true)
	i := &Image{
		width:  width,
		height: height,
		backend: &backend{
			restorable: r,
		},
	}
	runtime.SetFinalizer(i, (*Image).Dispose)
	return i
}

func NewScreenFramebufferImage(width, height int) *Image {
	backendsM.Lock()
	defer backendsM.Unlock()

	r := restorable.NewScreenFramebufferImage(width, height)
	i := &Image{
		width:  width,
		height: height,
		backend: &backend{
			restorable: r,
		},
	}
	runtime.SetFinalizer(i, (*Image).Dispose)
	return i
}

func InitializeGLState() error {
	backendsM.Lock()
	defer backendsM.Unlock()
	return restorable.InitializeGLState()
}

func ResolveStaleImages() error {
	backendsM.Lock()
	defer backendsM.Unlock()
	return restorable.ResolveStaleImages()
}

func IsRestoringEnabled() bool {
	// As IsRestoringEnabled is an immutable state, no need to lock here.
	return restorable.IsRestoringEnabled()
}

func Restore() error {
	backendsM.Lock()
	defer backendsM.Unlock()
	return restorable.Restore()
}

func Images() ([]image.Image, error) {
	backendsM.Lock()
	defer backendsM.Unlock()
	return restorable.Images()
}
<commit_msg>shareable: Bug fix: Don't mark disposed when the image becomes not shared<commit_after>// Copyright 2018 The Ebiten 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 shareable

import (
	"fmt"
	"image"
	"image/color"
	"runtime"

	"github.com/hajimehoshi/ebiten/internal/affine"
	"github.com/hajimehoshi/ebiten/internal/graphics"
	"github.com/hajimehoshi/ebiten/internal/opengl"
	"github.com/hajimehoshi/ebiten/internal/packing"
	"github.com/hajimehoshi/ebiten/internal/restorable"
	"github.com/hajimehoshi/ebiten/internal/sync"
)

type backend struct {
	restorable *restorable.Image

	// If page is nil, the backend is not shared.
	page *packing.Page
}

func (b *backend) TryAlloc(width, height int) (*packing.Node, bool) {
	// If the region is allocated without any extention, it's fine.
	if n := b.page.Alloc(width, height); n != nil {
		return n, true
	}

	// Simulate the extending the page and calculate the appropriate page size.
	page := b.page.Clone()
	nExtended := 0
	for {
		if !page.Extend() {
			// The page can't be extended any more. Return as failure.
			return nil, false
		}
		nExtended++
		if n := page.Alloc(width, height); n != nil {
			break
		}
	}

	for i := 0; i < nExtended; i++ {
		b.page.Extend()
	}
	s := b.page.Size()
	newImg := restorable.NewImage(s, s, false)
	oldImg := b.restorable
	w, h := oldImg.Size()
	newImg.DrawImage(oldImg, 0, 0, w, h, nil, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
	oldImg.Dispose()
	b.restorable = newImg

	n := b.page.Alloc(width, height)
	if n == nil {
		panic("not reached")
	}
	return n, true
}

var (
	// backendsM is a mutex for critical sections of the backend and packing.Node objects.
	backendsM sync.Mutex

	// theBackends is a set of actually shared images.
	theBackends = []*backend{}
)

type Image struct {
	width    int
	height   int
	disposed bool

	backend *backend

	// If node is nil, the image is not shared.
	node *packing.Node
}

func (i *Image) ensureNotShared() {
	if i.backend == nil {
		i.allocate(false)
		return
	}

	if i.node == nil {
		return
	}

	x, y, w, h := i.region()
	newImg := restorable.NewImage(w, h, false)
	newImg.DrawImage(i.backend.restorable, x, y, x+w, y+h, nil, nil, opengl.CompositeModeCopy, graphics.FilterNearest)

	i.dispose(false)
	i.backend = &backend{
		restorable: newImg,
	}
}

func (i *Image) region() (x, y, width, height int) {
	if i.backend == nil {
		panic("not reached")
	}
	if i.node == nil {
		w, h := i.backend.restorable.Size()
		return 0, 0, w, h
	}
	return i.node.Region()
}

func (i *Image) Size() (width, height int) {
	return i.width, i.height
}

func (i *Image) DrawImage(img *Image, sx0, sy0, sx1, sy1 int, geom *affine.GeoM, colorm *affine.ColorM, mode opengl.CompositeMode, filter graphics.Filter) {
	backendsM.Lock()
	defer backendsM.Unlock()

	if img.disposed {
		panic("shareable: the drawing source image must not be disposed")
	}
	if i.disposed {
		panic("shareable: the drawing target image must not be disposed")
	}
	if img.backend == nil {
		img.allocate(true)
	}

	i.ensureNotShared()

	// Compare i and img after ensuring i is not shared, or
	// i and img might share the same texture even though i != img.
	if i.backend.restorable == img.backend.restorable {
		panic("shareable: Image.DrawImage: img must be different from the receiver")
	}

	dx, dy, _, _ := img.region()
	sx0 += dx
	sy0 += dy
	sx1 += dx
	sy1 += dy
	i.backend.restorable.DrawImage(img.backend.restorable, sx0, sy0, sx1, sy1, geom, colorm, mode, filter)
}

func (i *Image) ReplacePixels(p []byte) {
	backendsM.Lock()
	defer backendsM.Unlock()

	if i.disposed {
		panic("shareable: the image must not be disposed")
	}
	if i.backend == nil {
		i.allocate(true)
	}

	x, y, w, h := i.region()
	if l := 4 * w * h; len(p) != l {
		panic(fmt.Sprintf("shareable: len(p) was %d but must be %d", len(p), l))
	}
	i.backend.restorable.ReplacePixels(p, x, y, w, h)
}

func (i *Image) At(x, y int) (color.Color, error) {
	backendsM.Lock()
	defer backendsM.Unlock()

	if i.backend == nil {
		return color.RGBA{}, nil
	}

	ox, oy, w, h := i.region()
	if x < 0 || y < 0 || x >= w || y >= h {
		return color.RGBA{}, nil
	}

	clr, err := i.backend.restorable.At(x+ox, y+oy)
	return clr, err
}

func (i *Image) Dispose() {
	backendsM.Lock()
	defer backendsM.Unlock()
	i.dispose(true)
}

func (i *Image) dispose(markDisposed bool) {
	defer func() {
		if markDisposed {
			i.disposed = true
		}
		i.backend = nil
		i.node = nil
		runtime.SetFinalizer(i, nil)
	}()

	if i.disposed {
		return
	}

	if i.backend == nil {
		// Not allocated yet.
		return
	}

	if i.node == nil {
		i.backend.restorable.Dispose()
		return
	}

	i.backend.page.Free(i.node)
	if !i.backend.page.IsEmpty() {
		// As this part can be reused, this should be cleared explicitly.
		x0, y0, x1, y1 := i.region()
		i.backend.restorable.ReplacePixels(nil, x0, y0, x1, y1)
		return
	}

	i.backend.restorable.Dispose()
	index := -1
	for idx, sh := range theBackends {
		if sh == i.backend {
			index = idx
			break
		}
	}
	if index == -1 {
		panic("not reached")
	}
	theBackends = append(theBackends[:index], theBackends[index+1:]...)
}

func (i *Image) IsInvalidated() (bool, error) {
	backendsM.Lock()
	defer backendsM.Unlock()
	v, err := i.backend.restorable.IsInvalidated()
	return v, err
}

func NewImage(width, height int) *Image {
	// Actual allocation is done lazily.
	return &Image{
		width:  width,
		height: height,
	}
}

func (i *Image) allocate(shareable bool) {
	if i.backend != nil {
		panic("not reached")
	}

	const (
		initSize = 1024
		maxSize  = 4096
	)

	if !shareable || i.width > maxSize || i.height > maxSize {
		i.backend = &backend{
			restorable: restorable.NewImage(i.width, i.height, false),
		}
		return
	}

	for _, b := range theBackends {
		if n, ok := b.TryAlloc(i.width, i.height); ok {
			i.backend = b
			i.node = n
			return
		}
	}
	size := initSize
	for i.width > size || i.height > size {
		if size == maxSize {
			panic("not reached")
		}
		size *= 2
	}

	b := &backend{
		restorable: restorable.NewImage(size, size, false),
		page:       packing.NewPage(size, maxSize),
	}
	theBackends = append(theBackends, b)

	n := b.page.Alloc(i.width, i.height)
	if n == nil {
		panic("not reached")
	}
	i.backend = b
	i.node = n
	runtime.SetFinalizer(i, (*Image).Dispose)
	return
}

func NewVolatileImage(width, height int) *Image {
	backendsM.Lock()
	defer backendsM.Unlock()

	r := restorable.NewImage(width, height, true)
	i := &Image{
		width:  width,
		height: height,
		backend: &backend{
			restorable: r,
		},
	}
	runtime.SetFinalizer(i, (*Image).Dispose)
	return i
}

func NewScreenFramebufferImage(width, height int) *Image {
	backendsM.Lock()
	defer backendsM.Unlock()

	r := restorable.NewScreenFramebufferImage(width, height)
	i := &Image{
		width:  width,
		height: height,
		backend: &backend{
			restorable: r,
		},
	}
	runtime.SetFinalizer(i, (*Image).Dispose)
	return i
}

func InitializeGLState() error {
	backendsM.Lock()
	defer backendsM.Unlock()
	return restorable.InitializeGLState()
}

func ResolveStaleImages() error {
	backendsM.Lock()
	defer backendsM.Unlock()
	return restorable.ResolveStaleImages()
}

func IsRestoringEnabled() bool {
	// As IsRestoringEnabled is an immutable state, no need to lock here.
	return restorable.IsRestoringEnabled()
}

func Restore() error {
	backendsM.Lock()
	defer backendsM.Unlock()
	return restorable.Restore()
}

func Images() ([]image.Image, error) {
	backendsM.Lock()
	defer backendsM.Unlock()
	return restorable.Images()
}
<|endoftext|>


<commit_before>package main

import "time"

type BlogPost struct {
	Id int64 `json:"id"`
	Titel string `json:"titel"`
	Text string `json:"text"`
	Auteur string `json:"auteur"`
	Img_url string `json:"img_url"`
	Ctime time.Time `json:"ctime"`
	Image string `json:"image"`
}

type SpinData struct {
	Id int64 `json:"id"`
	Tijd time.Time `json:"tijd"`
	Mode string `json:"mode"`
	Hellingsgraad int64 `json:"hellingsgraad"`
	Snelheid int64 `json:"snelheid"`
	Batterij int64 `json:"batterij"`
	BallonCount int64 `json:"ballonCount"`
}

type ServoData struct {
	Id int64 `json:"id"`
	ServoId int64 `json:"servo_id"`
	Tijd time.Time `json:"tijd"`
	Voltage int64 `json:"voltage"`
	Positie int64 `json:"positie"`
	Load int64 `json:"load"`
	Temperatuur int64 `json:"temperatuur"`
}

type LogData struct {
	Id int64 `json:"id"`
	Log int64 `json:"log"`
}<commit_msg>screw SSE<commit_after>package main

import "time"

type BlogPost struct {
	Id int64 `json:"id"`
	Titel string `json:"titel"`
	Text string `json:"text"`
	Auteur string `json:"auteur"`
	Img_url string `json:"img_url"`
	Ctime time.Time `json:"ctime"`
	Image string `json:"image"`
}

type SpinData struct {
	Id int64 `json:"id"`
	Tijd time.Time `json:"tijd"`
	Mode string `json:"mode"`
	Hellingsgraad int64 `json:"hellingsgraad"`
	Snelheid int64 `json:"snelheid"`
	Batterij int64 `json:"batterij"`
	BallonCount int64 `json:"ballonCount"`
}

type ServoData struct {
	Id int64 `json:"id"`
	ServoId int64 `json:"servo_id"`
	Tijd time.Time `json:"tijd"`
	Voltage int64 `json:"voltage"`
	Positie int64 `json:"positie"`
	Load int64 `json:"load"`
	Temperatuur int64 `json:"temperatuur"`
}

type LogData struct {
	Id int64 `json:"id"`
	Log string `json:"log"`
}<|endoftext|>


<commit_before>package gom

import (
	"errors"
	"fmt"
	"log"
	"reflect"
	"strings"
	"time"
)

func IsEmpty(v interface{}) bool {
	times := time.Time{}
	if times == v {
		return true
	}
	if v == "" {
		return true
	}
	if v == 0 {
		return true
	}
	if v == 0.0 {
		return true
	}
	if v == nil {
		return true
	}
	return false
}
func getType(v interface{}) (reflect.Type, bool, bool) {
	tt := reflect.TypeOf(v)
	isPtr := false
	islice := false
	if tt.Kind() == reflect.Ptr {
		tt = tt.Elem()
		isPtr = true
	}
	if tt.Kind() == reflect.Slice || tt.Kind() == reflect.Array {
		tt = tt.Elem()
		islice = true
	}
	if debug {
		fmt.Println("Test getType, result:", tt, isPtr, islice)
	}
	return tt, isPtr, islice
}

func GetTableModel(v interface{}, names ...string) (TableModel, error) {
	tms, err := getTableModel(v)
	if err != nil {
		return TableModel{}, nil
	}
	tm := tms[0]
	var cc []Column
	for _, ct := range tm.Columns {
		for _, name := range names {
			if ct.ColumnName == name {
				cc = append(cc, ct)
			}
		}
	}
	tm.Columns = cc
	return tm, nil

}
func CreateSingleValueTableModel(v interface{}, table string, field string) TableModel {
	tt, _, _ := getType(v)
	vals := reflect.New(tt).Elem()
	columns := []Column{{ColumnName: field, ColumnType: tt, IsPrimary: false, Auto: false}}
	return TableModel{Columns: columns, TableName: table, ModelType: tt, ModelValue: vals}
}
func getTableModels(vs ...interface{}) ([]TableModel, error) {
	tablemodels := []TableModel{}
	for _, v := range vs {
		tt, _, _ := getType(v)
		if tt.Kind() == reflect.Interface {
			return tablemodels, errors.New("can't use interface as struct")
		}
		tbs, err := getTableModel(v)
		if err != nil {
			return tablemodels, err
		}
		tablemodels = append(tablemodels, tbs...)
	}
	return tablemodels, nil
}
func getTableModel(v interface{}) ([]TableModel, error) {
	var tableModels []TableModel
	var values []reflect.Value
	tt, isPtr, isSlice := getType(v)
	if tt.NumField() == 0 || tt.NumMethod() == 0 {
		return tableModels, errors.New(tt.Name() + " is not a valid struct")
	}
	value := reflect.ValueOf(v)
	if v != nil && tt.Kind() != reflect.Interface {

		if isPtr {
			value = value.Elem()
		}
		if debug {
			fmt.Println("model info:", tt, isPtr, isSlice, value)
		}
		if isSlice {
			if value.Len() > 0 {
				for i := 0; i < value.Len(); i++ {
					val := value.Index(i)
					values = append(values, val)
				}
			} else {
				values = append(values, reflect.New(tt).Elem())
			}
		} else {
			values = append(values, value)
		}
		if debug {
			fmt.Println(values)
		}
		for _, val := range values {
			nameMethod := val.MethodByName("TableName")
			if debug {
				fmt.Println(nameMethod)
			}
			tableName := nameMethod.Call(nil)[0].String()
			columns, primary := getColumns(val)
			ccs := []Column{primary}
			ccs = append(ccs, columns...)
			tableModels = append(tableModels, TableModel{ModelType: tt, ModelValue: val, Columns: ccs, TableName: tableName, Primary: primary})
		}
		return tableModels, nil

	} else {
		return tableModels, errors.New("can't use interface to build TableModel")
	}
}
func getColumns(v reflect.Value) ([]Column, Column) {
	var columns []Column
	var primary Column
	results := reflect.Indirect(reflect.ValueOf(&columns))
	oo := v.Type()

	for i := 0; i < oo.NumField(); i++ {
		field := oo.Field(i)
		col, tps := getColumnFromField(field)
		if tps != -1 {
			if tps == 1 || tps == 2 {
				primary = col
			} else {
				n := reflect.Indirect(reflect.ValueOf(&col))
				if results.Kind() == reflect.Ptr {
					results.Set(reflect.Append(results, n.Addr()))
				} else {
					results.Set(reflect.Append(results, n))
				}
			}

		}
	}
	if debug {
		fmt.Println("columns is:", columns)
	}
	return columns, primary
}
func getColumnFromField(filed reflect.StructField) (Column, int) {
	tag, tps := getTagFromField(filed)
	if debug {
		fmt.Println("Tag is:", tag, "type is:", tps)
	}
	if tps != -1 {
		return Column{ColumnType: filed.Type, ColumnName: tag, FieldName: filed.Name, Auto: tps == 2, IsPrimary: tps == 1 || tps == 2}, tps
	} else {
		return Column{}, -1
	}

}
func getTagFromField(field reflect.StructField) (string, int) {
	tag, hasTag := field.Tag.Lookup("gom")
	if hasTag {
		if strings.EqualFold(tag, "-") || len(tag) == 0 {
			return "", -1
		} else if len(tag) == 1 {
			tps := 0
			if strings.EqualFold(tag, "@") {
				tps = 2
			}
			if strings.EqualFold(tag, "!") {
				tps = 1
			}
			return strings.ToLower(field.Name), tps
		} else {
			if strings.Contains(tag, ",") {
				tags := strings.Split(tag, ",")
				if len(tags) == 2 {
					if strings.EqualFold(tags[0], "!") || strings.EqualFold(tags[0], "primary") {
						return tags[1], 1
					} else if strings.EqualFold(tags[0], "@") || strings.EqualFold(tags[0], "auto") {
						return tags[1], 2
					} else if strings.EqualFold(tags[0], "#") || strings.EqualFold(tags[0], "column") {
						return tags[1], 0
					} else {
						return "", -1
					}
				} else {
					return "", -1
				}
			} else {
				return tag, 0
			}
		}
	} else {
		return "", -1
	}
}
func getValueOfTableRow(model TableModel, row RowChooser) reflect.Value {
	maps := getBytesMap(model, row)
	ccs := model.Columns
	vv := reflect.New(model.ModelType).Elem()
	isStruct := model.ModelType.Kind() == reflect.Struct && model.ModelType != reflect.TypeOf(time.Time{})
	for _, c := range ccs {
		vi := reflect.New(c.ColumnType).Elem()
		var dds interface{}
		dbytes := maps[c.ColumnName]
		data := string(dbytes)

		switch v := vi.Interface().(type) {

		case BinaryUnmarshaler:
			dd, er := v.UnmarshalBinary(dbytes)
			debugs("jump into BinaryUnmarsh====", v)
			if er != nil {
				log.Fatalln("when convert binary data to '", vv.Kind().String(), "', find error:", er.Error())
			}
			dds = dd
		case uint:
			dds, _ = UIntfromString(data)
		case uint16:
			dds, _ = UInt16fromString(data)
		case uint32:
			dds, _ = UInt32fromString(data)
		case uint64:
			dds, _ = UInt64fromString(data)
		case int:
			dds, _ = IntfromString(data)
		case int8:
			dds, _ = Int8fromString(data)
		case int16:
			dds, _ = Int16fromString(data)
		case int32:
			dds, _ = Int32fromString(data)
		case int64:
			dds, _ = Int64fromString(data)
		case float32:
			dds, _ = Float32fromString(data)
		case float64:
			dds, _ = Float64fromString(data)
		case string:
			dds = data
		case []byte:
			dds = dbytes
		case time.Time:
			dds, _ = TimeFromString(data)
		default:

			dds = data
		}
		if isStruct {
			vv.FieldByName(c.FieldName).Set(reflect.ValueOf(dds))
		} else {
			vv.Set(reflect.ValueOf(dds))
		}
	}
	return vv
}
func getBytesMap(model TableModel, row RowChooser) map[string][]byte {

	data := make([][]byte, len(model.Columns))
	dest := make([]interface{}, len(model.Columns)) // A temporary interface{} slice
	for i, _ := range data {
		dest[i] = &data[i] // Put pointers to each string in the interface slice
	}
	err := row.Scan(dest...)
	if err != nil {
		return map[string][]byte{}
	}
	result := make(map[string][]byte, len(model.Columns))
	ccs := model.Columns
	for i, dd := range ccs {
		result[dd.ColumnName] = data[i]
	}
	return result

}
<commit_msg>修复无法使用自定义对象的bug<commit_after>package gom

import (
	"errors"
	"fmt"
	"log"
	"reflect"
	"strings"
	"time"
)

func IsEmpty(v interface{}) bool {
	times := time.Time{}
	if times == v {
		return true
	}
	if v == "" {
		return true
	}
	if v == 0 {
		return true
	}
	if v == 0.0 {
		return true
	}
	if v == nil {
		return true
	}
	return false
}
func getType(v interface{}) (reflect.Type, bool, bool) {
	tt := reflect.TypeOf(v)
	isPtr := false
	islice := false
	if tt.Kind() == reflect.Ptr {
		tt = tt.Elem()
		isPtr = true
	}
	if tt.Kind() == reflect.Slice || tt.Kind() == reflect.Array {
		tt = tt.Elem()
		islice = true
	}
	if debug {
		fmt.Println("Test getType, result:", tt, isPtr, islice)
	}
	return tt, isPtr, islice
}

func GetTableModel(v interface{}, names ...string) (TableModel, error) {
	tms, err := getTableModel(v)
	if err != nil {
		return TableModel{}, nil
	}
	tm := tms[0]
	var cc []Column
	for _, ct := range tm.Columns {
		for _, name := range names {
			if ct.ColumnName == name {
				cc = append(cc, ct)
			}
		}
	}
	tm.Columns = cc
	return tm, nil

}
func CreateSingleValueTableModel(v interface{}, table string, field string) TableModel {
	tt, _, _ := getType(v)
	vals := reflect.New(tt).Elem()
	columns := []Column{{ColumnName: field, ColumnType: tt, IsPrimary: false, Auto: false}}
	return TableModel{Columns: columns, TableName: table, ModelType: tt, ModelValue: vals}
}
func getTableModels(vs ...interface{}) ([]TableModel, error) {
	tablemodels := []TableModel{}
	for _, v := range vs {
		tt, _, _ := getType(v)
		if tt.Kind() == reflect.Interface {
			return tablemodels, errors.New("can't use interface as struct")
		}
		tbs, err := getTableModel(v)
		if err != nil {
			return tablemodels, err
		}
		tablemodels = append(tablemodels, tbs...)
	}
	return tablemodels, nil
}
func getTableModel(v interface{}) ([]TableModel, error) {
	var tableModels []TableModel
	var values []reflect.Value
	tt, isPtr, isSlice := getType(v)
	if tt.NumField() == 0 || tt.NumMethod() == 0 {
		return tableModels, errors.New(tt.Name() + " is not a valid struct")
	}
	value := reflect.ValueOf(v)
	if v != nil && tt.Kind() != reflect.Interface {

		if isPtr {
			value = value.Elem()
		}
		if debug {
			fmt.Println("model info:", tt, isPtr, isSlice, value)
		}
		if isSlice {
			if value.Len() > 0 {
				for i := 0; i < value.Len(); i++ {
					val := value.Index(i)
					values = append(values, val)
				}
			} else {
				values = append(values, reflect.New(tt).Elem())
			}
		} else {
			values = append(values, value)
		}
		if debug {
			fmt.Println(values)
		}
		for _, val := range values {
			nameMethod := val.MethodByName("TableName")
			if debug {
				fmt.Println(nameMethod)
			}
			tableName := nameMethod.Call(nil)[0].String()
			columns, primary := getColumns(val)
			ccs := []Column{primary}
			ccs = append(ccs, columns...)
			tableModels = append(tableModels, TableModel{ModelType: tt, ModelValue: val, Columns: ccs, TableName: tableName, Primary: primary})
		}
		return tableModels, nil

	} else {
		return tableModels, errors.New("can't use interface to build TableModel")
	}
}
func getColumns(v reflect.Value) ([]Column, Column) {
	var columns []Column
	var primary Column
	results := reflect.Indirect(reflect.ValueOf(&columns))
	oo := v.Type()

	for i := 0; i < oo.NumField(); i++ {
		field := oo.Field(i)
		col, tps := getColumnFromField(field)
		if tps != -1 {
			if tps == 1 || tps == 2 {
				primary = col
			} else {
				n := reflect.Indirect(reflect.ValueOf(&col))
				if results.Kind() == reflect.Ptr {
					results.Set(reflect.Append(results, n.Addr()))
				} else {
					results.Set(reflect.Append(results, n))
				}
			}

		}
	}
	if debug {
		fmt.Println("columns is:", columns)
	}
	return columns, primary
}
func getColumnFromField(filed reflect.StructField) (Column, int) {
	tag, tps := getTagFromField(filed)
	if debug {
		fmt.Println("Tag is:", tag, "type is:", tps)
	}
	if tps != -1 {
		return Column{ColumnType: filed.Type, ColumnName: tag, FieldName: filed.Name, Auto: tps == 2, IsPrimary: tps == 1 || tps == 2}, tps
	} else {
		return Column{}, -1
	}

}
func getTagFromField(field reflect.StructField) (string, int) {
	tag, hasTag := field.Tag.Lookup("gom")
	if hasTag {
		if strings.EqualFold(tag, "-") || len(tag) == 0 {
			return "", -1
		} else if len(tag) == 1 {
			tps := 0
			if strings.EqualFold(tag, "@") {
				tps = 2
			}
			if strings.EqualFold(tag, "!") {
				tps = 1
			}
			return strings.ToLower(field.Name), tps
		} else {
			if strings.Contains(tag, ",") {
				tags := strings.Split(tag, ",")
				if len(tags) == 2 {
					if strings.EqualFold(tags[0], "!") || strings.EqualFold(tags[0], "primary") {
						return tags[1], 1
					} else if strings.EqualFold(tags[0], "@") || strings.EqualFold(tags[0], "auto") {
						return tags[1], 2
					} else if strings.EqualFold(tags[0], "#") || strings.EqualFold(tags[0], "column") {
						return tags[1], 0
					} else {
						return "", -1
					}
				} else {
					return "", -1
				}
			} else {
				return tag, 0
			}
		}
	} else {
		return "", -1
	}
}
func getValueOfTableRow(model TableModel, row RowChooser) reflect.Value {
	maps := getBytesMap(model, row)
	ccs := model.Columns
	vv := reflect.New(model.ModelType).Elem()
	isStruct := model.ModelType.Kind() == reflect.Struct && model.ModelType != reflect.TypeOf(time.Time{})
	for _, c := range ccs {
		vi := reflect.New(c.ColumnType).Elem()
		var dds interface{}
		dbytes := maps[c.ColumnName]
		data := string(dbytes)

		switch v := vi.Interface().(type) {

		case BinaryUnmarshaler:
			dd, er := v.UnmarshalBinary(dbytes)
			debugs("jump into BinaryUnmarsh====", dd)
			if er != nil {
				log.Fatalln("when convert binary data to '", vv.Kind().String(), "', find error:", er.Error())
			}
			dds = dd
		case uint:
			dds, _ = UIntfromString(data)
		case uint16:
			dds, _ = UInt16fromString(data)
		case uint32:
			dds, _ = UInt32fromString(data)
		case uint64:
			dds, _ = UInt64fromString(data)
		case int:
			dds, _ = IntfromString(data)
		case int8:
			dds, _ = Int8fromString(data)
		case int16:
			dds, _ = Int16fromString(data)
		case int32:
			dds, _ = Int32fromString(data)
		case int64:
			dds, _ = Int64fromString(data)
		case float32:
			dds, _ = Float32fromString(data)
		case float64:
			dds, _ = Float64fromString(data)
		case string:
			dds = data
		case []byte:
			dds = dbytes
		case time.Time:
			dds, _ = TimeFromString(data)
		default:

			dds = data
		}
		if isStruct {
			vv.FieldByName(c.FieldName).Set(reflect.ValueOf(dds))
		} else {
			vv.Set(reflect.ValueOf(dds))
		}
	}
	return vv
}
func getBytesMap(model TableModel, row RowChooser) map[string][]byte {

	data := make([][]byte, len(model.Columns))
	dest := make([]interface{}, len(model.Columns)) // A temporary interface{} slice
	for i, _ := range data {
		dest[i] = &data[i] // Put pointers to each string in the interface slice
	}
	err := row.Scan(dest...)
	if err != nil {
		return map[string][]byte{}
	}
	result := make(map[string][]byte, len(model.Columns))
	ccs := model.Columns
	for i, dd := range ccs {
		result[dd.ColumnName] = data[i]
	}
	return result

}
<|endoftext|>


<commit_before>package cryptopals

import (
	"encoding/base64"
	"encoding/hex"
	"fmt"
	"strings"
)

// HexToBase64 takes a hex encoded byte array and returns a base 64 encoded
// byte array, a function that only operates upon a byte repr is desirable
// in terms of effiency
func HexToBase64(src []byte) []byte {
	// so the different representations - hex and base64 take up different
	// amounts of bytes
	dest := make([]byte, base64.StdEncoding.EncodedLen(len(src)))
	base64.StdEncoding.Encode(dest, src)
	return dest
}

// HexStringToBase64String is a utility function, not intended for heavy use
// due to string conversions
func HexStringToBase64String(h string) string {
	b, err := hex.DecodeString(h)
	if err != nil {
		panic(err)
	}
	b64 := HexToBase64(b)
	return string(b64)
}

// Xor takes two equal length buffers and returns their XOR combination
func Xor(b1, b2 []byte) []byte {
	l := len(b1)
	if len(b2) != l {
		panic(fmt.Sprintf("Xor does not accept unequal length args len(b1)=%d, len(b2)=%d",
			len(b1), len(b2)))
	}
	out := make([]byte, l)
	for i := 0; i < l; i++ {
		out[i] = b1[i] ^ b2[i]
	}
	return out
}

type Result struct {
	Plaintext string
	Cypher    int
	Score     int
}

// BruteforceXOR searches for a single character XOR cypher that yields the
// most likely plaintext
func BruteforceXOR(bIn1 []byte) *Result {
	topResult := &Result{}
	// cycle through possible cyphers
	for i := 0; i < 128; i++ {
		// construct equal sized cypher array for passing to Xor
		bIn2 := make([]byte, len(bIn1))
		for j := 0; j < len(bIn1); j++ {
			bIn2[j] = byte(i)
		}
		s := string(Xor(bIn1, bIn2))
		r := &Result{
			Plaintext: s,
			Cypher:    i,
			Score:     ScorePlaintext(s),
		}
		if r.Score > topResult.Score {
			topResult = r
		}
	}
	return topResult

}

// ScorePlaintext scores a string for confidence that is plaintext, the higher the score,
// the higher the confidence
func ScorePlaintext(s string) int {
	popular := "uldrhsnioate" // "etaoinshrdlu" // reversed

	var total int
	for i := 0; i < len(s); i++ {
		subscore := strings.Index(popular, string(s[i]))
		if subscore != -1 {
			total += subscore
		}
	}
	return total
}
<commit_msg>util: optimise Xor for memory<commit_after>package cryptopals

import (
	"encoding/base64"
	"encoding/hex"
	"fmt"
	"strings"
)

// HexToBase64 takes a hex encoded byte array and returns a base 64 encoded
// byte array, a function that only operates upon a byte repr is desirable
// in terms of effiency
func HexToBase64(src []byte) []byte {
	// so the different representations - hex and base64 take up different
	// amounts of bytes
	dest := make([]byte, base64.StdEncoding.EncodedLen(len(src)))
	base64.StdEncoding.Encode(dest, src)
	return dest
}

// HexStringToBase64String is a utility function, not intended for heavy use
// due to string conversions
func HexStringToBase64String(h string) string {
	b, err := hex.DecodeString(h)
	if err != nil {
		panic(err)
	}
	b64 := HexToBase64(b)
	return string(b64)
}

// Xor takes two buffers and returns their XOR combination
// b2 can be shorter in length than b1, if so b2 will repeat
func Xor(b1, b2 []byte) []byte {
	l := len(b1)
	if len(b2) > l {
		panic(fmt.Sprintf("Xor does not accept b2 longer than b1, args len(b1)=%d, len(b2)=%d",
			len(b1), len(b2)))
	}
	out := make([]byte, l)
	b2Index := 0
	for i := 0; i < l; i++ {
		out[i] = b1[i] ^ b2[b2Index]
		b2Index++
		if b2Index == len(b2) {
			b2Index = 0
		}
	}
	return out
}

type Result struct {
	Plaintext string
	Cypher    int
	Score     int
}

// BruteforceXOR searches for a single character XOR cypher that yields the
// most likely plaintext
func BruteforceXOR(bIn1 []byte) *Result {
	topResult := &Result{}
	// cycle through possible cyphers
	for i := 0; i < 128; i++ {
		// construct equal sized cypher array for passing to Xor
		bIn2 := []byte{byte(i)}
		s := string(Xor(bIn1, bIn2))
		r := &Result{
			Plaintext: s,
			Cypher:    i,
			Score:     ScorePlaintext(s),
		}
		if r.Score > topResult.Score {
			topResult = r
		}
	}
	return topResult

}

// ScorePlaintext scores a string for confidence that is plaintext, the higher the score,
// the higher the confidence
func ScorePlaintext(s string) int {
	popular := "uldrhsnioate" // "etaoinshrdlu" // reversed

	var total int
	for i := 0; i < len(s); i++ {
		subscore := strings.Index(popular, string(s[i]))
		if subscore != -1 {
			total += subscore
		}
	}
	return total
}
<|endoftext|>


<commit_before>// Copyright 2016 The Linux Foundation
//
// 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 v1

import "github.com/opencontainers/image-spec/specs-go"

// Platform describes the platform which the image in the manifest runs on.
type Platform struct {
	// Architecture field specifies the CPU architecture, for example
	// `amd64` or `ppc64`.
	Architecture string `json:"architecture"`

	// OS specifies the operating system, for example `linux` or `windows`.
	OS string `json:"os"`

	// OSVersion is an optional field specifying the operating system
	// version, for example `10.0.10586`.
	OSVersion string `json:"os.version,omitempty"`

	// OSFeatures is an optional field specifying an array of strings,
	// each listing a required OS feature (for example on Windows `win32k`).
	OSFeatures []string `json:"os.features,omitempty"`

	// Variant is an optional field specifying a variant of the CPU, for
	// example `ppc64le` to specify a little-endian version of a PowerPC CPU.
	Variant string `json:"variant,omitempty"`

	// Features is an optional field specifying an array of strings, each
	// listing a required CPU feature (for example `sse4` or `aes`).
	Features []string `json:"features,omitempty"`
}

// ManifestDescriptor describes a platform specific manifest.
type ManifestDescriptor struct {
	Descriptor

	// Platform describes the platform which the image in the manifest runs on.
	Platform Platform `json:"platform,omitempty"`
}

// Index references manifests for various platforms.
// This structure provides `application/vnd.oci.image.index.v1+json` mediatype when marshalled to JSON.
type Index struct {
	specs.Versioned

	// Manifests references platform specific manifests.
	Manifests []ManifestDescriptor `json:"manifests"`

	// Annotations contains arbitrary metadata for the image index.
	Annotations map[string]string `json:"annotations,omitempty"`
}
<commit_msg>Make the Platform field actually optional.<commit_after>// Copyright 2016 The Linux Foundation
//
// 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 v1

import "github.com/opencontainers/image-spec/specs-go"

// Platform describes the platform which the image in the manifest runs on.
type Platform struct {
	// Architecture field specifies the CPU architecture, for example
	// `amd64` or `ppc64`.
	Architecture string `json:"architecture"`

	// OS specifies the operating system, for example `linux` or `windows`.
	OS string `json:"os"`

	// OSVersion is an optional field specifying the operating system
	// version, for example `10.0.10586`.
	OSVersion string `json:"os.version,omitempty"`

	// OSFeatures is an optional field specifying an array of strings,
	// each listing a required OS feature (for example on Windows `win32k`).
	OSFeatures []string `json:"os.features,omitempty"`

	// Variant is an optional field specifying a variant of the CPU, for
	// example `ppc64le` to specify a little-endian version of a PowerPC CPU.
	Variant string `json:"variant,omitempty"`

	// Features is an optional field specifying an array of strings, each
	// listing a required CPU feature (for example `sse4` or `aes`).
	Features []string `json:"features,omitempty"`
}

// ManifestDescriptor describes a platform specific manifest.
type ManifestDescriptor struct {
	Descriptor

	// Platform describes the platform which the image in the manifest runs on.
	Platform *Platform `json:"platform,omitempty"`
}

// Index references manifests for various platforms.
// This structure provides `application/vnd.oci.image.index.v1+json` mediatype when marshalled to JSON.
type Index struct {
	specs.Versioned

	// Manifests references platform specific manifests.
	Manifests []ManifestDescriptor `json:"manifests"`

	// Annotations contains arbitrary metadata for the image index.
	Annotations map[string]string `json:"annotations,omitempty"`
}
<|endoftext|>


<commit_before>// Package util provides some helpers for working with GopherJS.
package util

import "github.com/neelance/gopherjs/js"

func Float64Slice(o js.Object) []float64 {
	d := o.Interface().([]interface{})
	ret := make([]float64, len(d))
	for i, e := range d {
		ret[i] = e.(float64)
	}
	return ret
}

func IntSlice(o js.Object) []int {
	d := o.Interface().([]interface{})
	ret := make([]int, len(d))
	for i, e := range d {
		ret[i] = int(e.(float64))
	}
	return ret
}

func StringSlice(o js.Object) []string {
	d := o.Interface().([]interface{})
	ret := make([]string, len(d))
	for i, e := range d {
		ret[i] = e.(string)
	}
	return ret
}

type Err struct {
	js.Object
	Message string `js:"message"`
	Name    string `js:"name"`
	File    string `js:"fileName"`   // Mozilla extension
	Line    int    `js:"lineNumber"` // Mozilla extension
	Stack   string `js:"stack"`      // Chrome/Microsoft extension
}

func (err Err) Error() string {
	return err.Message
}

func Error(o js.Object) error {
	if o.IsNull() {
		return nil
	}
	return Err{Object: o}
}
<commit_msg>fix gopherjs/js import path<commit_after>// Package util provides some helpers for working with GopherJS.
package util

import "github.com/gopherjs/gopherjs/js"

func Float64Slice(o js.Object) []float64 {
	d := o.Interface().([]interface{})
	ret := make([]float64, len(d))
	for i, e := range d {
		ret[i] = e.(float64)
	}
	return ret
}

func IntSlice(o js.Object) []int {
	d := o.Interface().([]interface{})
	ret := make([]int, len(d))
	for i, e := range d {
		ret[i] = int(e.(float64))
	}
	return ret
}

func StringSlice(o js.Object) []string {
	d := o.Interface().([]interface{})
	ret := make([]string, len(d))
	for i, e := range d {
		ret[i] = e.(string)
	}
	return ret
}

type Err struct {
	js.Object
	Message string `js:"message"`
	Name    string `js:"name"`
	File    string `js:"fileName"`   // Mozilla extension
	Line    int    `js:"lineNumber"` // Mozilla extension
	Stack   string `js:"stack"`      // Chrome/Microsoft extension
}

func (err Err) Error() string {
	return err.Message
}

func Error(o js.Object) error {
	if o.IsNull() {
		return nil
	}
	return Err{Object: o}
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"encoding/json"
	"github.com/hyperledger/fabric/core/chaincode/shim"
	"github.com/hyperledger/fabric/core/util"
)

type Chaincode struct { }

type ChaincodeFunctions struct {
	stub shim.ChaincodeStubInterface
}

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

func (t Chaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	_ = stub.PutState("deals", []byte("[]"))
	return nil, nil
}

func (t Chaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("invoke is running " + function)
	fns := ChaincodeFunctions{stub}
	if function == "registerDeal" {
		deploymentId := args[0]
		return fns.RegisterDeal(deploymentId)
	}
	return nil, errors.New("Received unknown function invocation: " + function)
}

func (t Chaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("query is running " + function)
	fns := ChaincodeFunctions{stub}
	if function == "ping" {
		return fns.Ping()
	} else if function == "getDeals" {
		return fns.GetDeals()
	}
	return nil, errors.New("Received unknown function query: " + function)
}

type DealConfig struct {
	DeploymentId 	string 		`json:"deploymentId"`
	Issuer 			string 		`json:"issuer"`
	Banks 			[]string 	`json:"banks"`
	BookStatus 		string 		`json:"bookStatus"`
	Price 			float64 	`json:"price"`
}

// Public Functions

func (c ChaincodeFunctions) Ping() ([]byte, error) {
    return []byte("pong"), nil
}

func (c ChaincodeFunctions) RegisterDeal(deploymentId string) ([]byte, error)  {
	c.saveDealToBlockChain(deploymentId)
	c.stub.SetEvent("New Deal Registered", []byte("{\"deploymentId\":\"" + deploymentId + "\"}"))
	return nil, nil
}

func (c ChaincodeFunctions) GetDeals() ([]byte, error) {
	companyBytes, _ := c.stub.ReadCertAttribute("company")
	roleBytes, _ := c.stub.ReadCertAttribute("role")
	company := string(companyBytes)
	role := string(roleBytes)
	deals := c.getDealsFromBlockchain()
	ret := make([]DealConfig, 0)
    for _, deal := range deals {
    	dealConfig := c.getDealConfig(deal)
        if permissionedForDeal(role, company, dealConfig) {
        	ret = append(ret, dealConfig)
        }
    }
    dealsJson, _ := json.Marshal(ret)
    return []byte(dealsJson), nil
}

// Private Functions

func (c ChaincodeFunctions) saveDealToBlockChain(deploymentId string) {
	deals := c.getDealsFromBlockchain()
	deals = append(deals, deploymentId)
	dealRegistryJson, _ := json.Marshal(deals)
	_ = c.stub.PutState("deals", []byte(dealRegistryJson))
}

func (c ChaincodeFunctions) getDealsFromBlockchain() []string {
	dealsJson, _ := c.stub.GetState("deals")
	var deals []string
	_ = json.Unmarshal(dealsJson, &deals)
	return deals
}

func (c ChaincodeFunctions) getDealConfig(address string) DealConfig {
	invokeArgs := util.ToChaincodeArgs("getDealConfig")
	dealConfigJson, _ := c.stub.QueryChaincode(address, invokeArgs)
	var dealConfig DealConfig
	_ = json.Unmarshal(dealConfigJson, &dealConfig)
	dealConfig.DeploymentId = address
	return dealConfig
}

func permissionedForDeal(role string, company string, dealConfig DealConfig) bool {
	if company == dealConfig.Issuer {
		return true
	} else if role == "bank" && stringInSlice(company, dealConfig.Banks) {
		return true
	} else if role == "investor" && dealConfig.BookStatus != "draft" {
		return true
	} else if role == "regulator" {
		return true
	} else if role == "clearing_house" && dealConfig.BookStatus == "confirmed" {
		return true
	} else {
		return false
	}
}

func stringInSlice(a string, list []string) bool {
    for _, b := range list {
        if b == a {
            return true
        }
    }
    return false
}<commit_msg>batch check-in<commit_after>package main

import (
	"errors"
	"fmt"
	"encoding/json"
	"github.com/hyperledger/fabric/core/chaincode/shim"
	"github.com/hyperledger/fabric/core/util"
)

type Chaincode struct { }

type ChaincodeFunctions struct {
	stub shim.ChaincodeStubInterface
}

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

func (t Chaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	_ = stub.PutState("deals", []byte("[]"))
	return nil, nil
}

func (t Chaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("invoke is running " + function)
	fns := ChaincodeFunctions{stub}
	if function == "registerDeal" {
		deploymentId := args[0]
		return fns.RegisterDeal(deploymentId)
	}
	return nil, errors.New("Received unknown function invocation: " + function)
}

func (t Chaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("query is running " + function)
	fns := ChaincodeFunctions{stub}
	if function == "ping" {
		return fns.Ping()
	} else if function == "getDeals" {
		return fns.GetDeals()
	}
	return nil, errors.New("Received unknown function query: " + function)
}

type DealConfig struct {
	DeploymentId 	string 		`json:"deploymentId"`
	Issuer 			string 		`json:"issuer"`
	Banks 			[]string 	`json:"banks"`
	BookStatus 		string 		`json:"bookStatus"`
	Price 			float64 	`json:"price"`
	RequiredDocs	[]string	`json:"requiredDocs"`
}

// Public Functions

func (c ChaincodeFunctions) Ping() ([]byte, error) {
    return []byte("pong"), nil
}

func (c ChaincodeFunctions) RegisterDeal(deploymentId string) ([]byte, error)  {
	c.saveDealToBlockChain(deploymentId)
	c.stub.SetEvent("New Deal Registered", []byte("{\"deploymentId\":\"" + deploymentId + "\"}"))
	return nil, nil
}

func (c ChaincodeFunctions) GetDeals() ([]byte, error) {
	companyBytes, _ := c.stub.ReadCertAttribute("company")
	roleBytes, _ := c.stub.ReadCertAttribute("role")
	company := string(companyBytes)
	role := string(roleBytes)
	deals := c.getDealsFromBlockchain()
	ret := make([]DealConfig, 0)
    for _, deal := range deals {
    	dealConfig := c.getDealConfig(deal)
        if permissionedForDeal(role, company, dealConfig) {
        	ret = append(ret, dealConfig)
        }
    }
    dealsJson, _ := json.Marshal(ret)
    return []byte(dealsJson), nil
}

// Private Functions

func (c ChaincodeFunctions) saveDealToBlockChain(deploymentId string) {
	deals := c.getDealsFromBlockchain()
	deals = append(deals, deploymentId)
	dealRegistryJson, _ := json.Marshal(deals)
	_ = c.stub.PutState("deals", []byte(dealRegistryJson))
}

func (c ChaincodeFunctions) getDealsFromBlockchain() []string {
	dealsJson, _ := c.stub.GetState("deals")
	var deals []string
	_ = json.Unmarshal(dealsJson, &deals)
	return deals
}

func (c ChaincodeFunctions) getDealConfig(address string) DealConfig {
	invokeArgs := util.ToChaincodeArgs("getDealConfig")
	dealConfigJson, _ := c.stub.QueryChaincode(address, invokeArgs)
	var dealConfig DealConfig
	_ = json.Unmarshal(dealConfigJson, &dealConfig)
	dealConfig.DeploymentId = address
	return dealConfig
}

func permissionedForDeal(role string, company string, dealConfig DealConfig) bool {
	if company == dealConfig.Issuer {
		return true
	} else if role == "bank" && stringInSlice(company, dealConfig.Banks) {
		return true
	} else if role == "investor" && dealConfig.BookStatus != "draft" {
		return true
	} else if role == "regulator" {
		return true
	} else if role == "clearing_house" && dealConfig.BookStatus == "confirmed" {
		return true
	} else {
		return false
	}
}

func stringInSlice(a string, list []string) bool {
    for _, b := range list {
        if b == a {
            return true
        }
    }
    return false
}<|endoftext|>


<commit_before>package migrations

import (
	"fmt"

	"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
)

func addTaskMigrations(mg *migrator.Migrator) {
	taskV1 := migrator.Table{
		Name: "task",
		Columns: []*migrator.Column{
			{Name: "id", Type: migrator.DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
			{Name: "name", Type: migrator.DB_NVarchar, Length: 255},
			{Name: "config", Type: migrator.DB_NVarchar, Length: 255},
			{Name: "interval", Type: migrator.DB_BigInt},
			{Name: "org_id", Type: migrator.DB_BigInt, Nullable: false},
			{Name: "enabled", Type: migrator.DB_Text},
			{Name: "route", Type: migrator.DB_Bool},
			{Name: "created", Type: migrator.DB_DateTime},
			{Name: "updated", Type: migrator.DB_DateTime},
		},
		Indices: []*migrator.Index{
			{Cols: []string{"org_id", "name"}, Type: migrator.UniqueIndex},
		},
	}
	mg.AddMigration("create task table v1", migrator.NewAddTableMigration(taskV1))
	for _, index := range taskV1.Indices {
		migrationId := fmt.Sprintf("create index %s - %s", index.XName(taskV1.Name), "v1")
		mg.AddMigration(migrationId, migrator.NewAddIndexMigration(taskV1, index))
	}
}
<commit_msg>fix SQL schema.<commit_after>package migrations

import (
	"fmt"

	"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
)

func addTaskMigrations(mg *migrator.Migrator) {
	taskV1 := migrator.Table{
		Name: "task",
		Columns: []*migrator.Column{
			{Name: "id", Type: migrator.DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
			{Name: "name", Type: migrator.DB_NVarchar, Length: 255},
			{Name: "config", Type: migrator.DB_Text},
			{Name: "interval", Type: migrator.DB_BigInt, Nullable: false},
			{Name: "org_id", Type: migrator.DB_BigInt, Nullable: false},
			{Name: "enabled", Type: migrator.DB_Bool},
			{Name: "route", Type: migrator.DB_Text, Nullable: false},
			{Name: "created", Type: migrator.DB_DateTime},
			{Name: "updated", Type: migrator.DB_DateTime},
		},
		Indices: []*migrator.Index{
			{Cols: []string{"org_id", "name"}, Type: migrator.UniqueIndex},
		},
	}
	mg.AddMigration("create task table v1", migrator.NewAddTableMigration(taskV1))
	for _, index := range taskV1.Indices {
		migrationId := fmt.Sprintf("create index %s - %s", index.XName(taskV1.Name), "v1")
		mg.AddMigration(migrationId, migrator.NewAddIndexMigration(taskV1, index))
	}
}
<|endoftext|>


<commit_before>// Copyright (C) 2013 by Maxim Bublis <b@codemonkey.ru>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

// This package provides implementation of Universally Unique Identifier (UUID).
// Supported versions are 1, 3, 4 and 5 (as specified in RFC 4122) and
// version 2 (as specified in DCE 1.1).
package uuid

import (
	"bytes"
	"crypto/md5"
	"crypto/rand"
	"crypto/sha1"
	"encoding/binary"
	"fmt"
	"hash"
	"net"
	"os"
	"time"
)

// UUID layout variants.
const (
	VariantNCS = iota
	VariantRFC4122
	VariantMicrosoft
	VariantFuture
)

// UUID DCE domains.
const (
	DomainPerson = iota
	DomainGroup
	DomainOrg
)

// Difference in 100-nanosecond intervals between
// UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970).
const epochStart = 122192928000000000

// UUID v1/v2 storage.
var (
	clockSequence uint16
	lastTime      uint64
	hardwareAddr  [6]byte
	posixUID      = uint32(os.Getuid())
	posixGID      = uint32(os.Getgid())
)

// Epoch calculation function
var epochFunc func() uint64

// Initialize storage
func init() {
	buf := make([]byte, 2)
	rand.Read(buf)
	clockSequence = binary.BigEndian.Uint16(buf)

	// Initialize hardwareAddr randomly in case
	// of real network interfaces absence
	rand.Read(hardwareAddr[:])

	interfaces, err := net.Interfaces()
	if err == nil {
		for _, iface := range interfaces {
			if len(iface.HardwareAddr) >= 6 {
				copy(hardwareAddr[:], iface.HardwareAddr)
				break
			}
		}
	}
	epochFunc = unixTimeFunc
}

// Returns difference in 100-nanosecond intervals between
// UUID epoch (October 15, 1582) and current time.
// This is default epoch calculation function.
func unixTimeFunc() uint64 {
	return epochStart + uint64(time.Now().UnixNano()/100)
}

// Returns current epoch calculation function.
func GetEpochFunc() func() uint64 {
	return epochFunc
}

// Sets epoch calculation function.
func SetEpochFunc(newEpochFunc func() uint64) {
	epochFunc = newEpochFunc
}

// UUID representation compliant with specification
// described in RFC 4122.
type UUID [16]byte

// Predefined namespace UUIDs.
var (
	NamespaceDNS  = UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
	NamespaceURL  = UUID{0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
	NamespaceOID  = UUID{0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
	NamespaceX500 = UUID{0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
)

// Returns true if u1 and u2 equals, otherwise returns false.
func Equal(u1 UUID, u2 UUID) bool {
	return bytes.Equal(u1[:], u2[:])
}

// Returns algorithm version used to generate UUID.
func (u UUID) Version() uint {
	return uint(u[6] >> 4)
}

// Returns UUID layout variant.
func (u UUID) Variant() uint {
	switch {
	case (u[8] & 0x80) == 0x00:
		return VariantNCS
	case (u[8]&0xc0)|0x80 == 0x80:
		return VariantRFC4122
	case (u[8]&0xe0)|0xc0 == 0xc0:
		return VariantMicrosoft
	}
	return VariantFuture
}

// Returns canonical string representation of UUID:
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
func (u UUID) String() string {
	return fmt.Sprintf("%x-%x-%x-%x-%x",
		u[:4], u[4:6], u[6:8], u[8:10], u[10:])
}

// Sets version bits.
func (u *UUID) SetVersion(v byte) {
	u[6] = (u[6] & 0x0f) | (v << 4)
}

// Sets variant bits as described in RFC 4122.
func (u *UUID) SetVariant() {
	u[8] = (u[8] & 0xbf) | 0x80
}

// Returns UUID epoch timestamp
func getTimestamp() uint64 {
	timeNow := epochStart + epochFunc()
	// Clock changed backwards since last UUID generation.
	// Should increase clock sequence.
	if timeNow <= lastTime {
		clockSequence++
	}
	lastTime = timeNow
	return timeNow
}

// Returns UUID based on current timestamp and MAC address.
func NewV1() UUID {
	u := UUID{}

	timeNow := getTimestamp()

	binary.BigEndian.PutUint32(u[0:], uint32(timeNow))
	binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
	binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
	binary.BigEndian.PutUint16(u[8:], clockSequence)

	copy(u[10:], hardwareAddr[:])

	u.SetVersion(1)
	u.SetVariant()

	return u
}

// Returns DCE Security UUID based on POSIX UID/GID.
func NewV2(domain byte) UUID {
	u := UUID{}

	switch domain {
	case DomainPerson:
		binary.BigEndian.PutUint32(u[0:], posixUID)
	case DomainGroup:
		binary.BigEndian.PutUint32(u[0:], posixGID)
	}

	timeNow := getTimestamp()

	binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
	binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
	binary.BigEndian.PutUint16(u[8:], clockSequence)
	u[9] = domain
	copy(u[10:], hardwareAddr[:])
	u.SetVersion(2)
	u.SetVariant()

	return u
}

// Returns UUID based on MD5 hash of namespace UUID and name.
func NewV3(ns UUID, name string) UUID {
	u := newFromHash(md5.New(), ns, name)
	u.SetVersion(3)
	u.SetVariant()

	return u
}

// Returns random generated UUID.
func NewV4() UUID {
	u := UUID{}
	rand.Read(u[:])
	u.SetVersion(4)
	u.SetVariant()

	return u
}

// Returns UUID based on SHA-1 hash of namespace UUID and name.
func NewV5(ns UUID, name string) UUID {
	u := newFromHash(sha1.New(), ns, name)
	u.SetVersion(5)
	u.SetVariant()

	return u
}

// Returns UUID based on hashing of namespace UUID and name.
func newFromHash(h hash.Hash, ns UUID, name string) UUID {
	u := UUID{}
	h.Write(ns[:])
	h.Write([]byte(name))
	copy(u[:], h.Sum(nil))

	return u
}
<commit_msg>Added bitwise AND and OR operations for UUID<commit_after>// Copyright (C) 2013 by Maxim Bublis <b@codemonkey.ru>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

// This package provides implementation of Universally Unique Identifier (UUID).
// Supported versions are 1, 3, 4 and 5 (as specified in RFC 4122) and
// version 2 (as specified in DCE 1.1).
package uuid

import (
	"bytes"
	"crypto/md5"
	"crypto/rand"
	"crypto/sha1"
	"encoding/binary"
	"fmt"
	"hash"
	"net"
	"os"
	"time"
)

// UUID layout variants.
const (
	VariantNCS = iota
	VariantRFC4122
	VariantMicrosoft
	VariantFuture
)

// UUID DCE domains.
const (
	DomainPerson = iota
	DomainGroup
	DomainOrg
)

// Difference in 100-nanosecond intervals between
// UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970).
const epochStart = 122192928000000000

// UUID v1/v2 storage.
var (
	clockSequence uint16
	lastTime      uint64
	hardwareAddr  [6]byte
	posixUID      = uint32(os.Getuid())
	posixGID      = uint32(os.Getgid())
)

// Epoch calculation function
var epochFunc func() uint64

// Initialize storage
func init() {
	buf := make([]byte, 2)
	rand.Read(buf)
	clockSequence = binary.BigEndian.Uint16(buf)

	// Initialize hardwareAddr randomly in case
	// of real network interfaces absence
	rand.Read(hardwareAddr[:])

	interfaces, err := net.Interfaces()
	if err == nil {
		for _, iface := range interfaces {
			if len(iface.HardwareAddr) >= 6 {
				copy(hardwareAddr[:], iface.HardwareAddr)
				break
			}
		}
	}
	epochFunc = unixTimeFunc
}

// Returns difference in 100-nanosecond intervals between
// UUID epoch (October 15, 1582) and current time.
// This is default epoch calculation function.
func unixTimeFunc() uint64 {
	return epochStart + uint64(time.Now().UnixNano()/100)
}

// Returns current epoch calculation function.
func GetEpochFunc() func() uint64 {
	return epochFunc
}

// Sets epoch calculation function.
func SetEpochFunc(newEpochFunc func() uint64) {
	epochFunc = newEpochFunc
}

// UUID representation compliant with specification
// described in RFC 4122.
type UUID [16]byte

// Predefined namespace UUIDs.
var (
	NamespaceDNS  = UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
	NamespaceURL  = UUID{0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
	NamespaceOID  = UUID{0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
	NamespaceX500 = UUID{0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
)

// Returns result of binary AND of two UUIDs.
func And(u1 UUID, u2 UUID) UUID {
	u := UUID{}
	for i := 0; i < 16; i++ {
		u[i] = u1[i] & u2[i]
	}
	return u
}

// Returns result of binary OR of two UUIDs.
func Or(u1 UUID, u2 UUID) UUID {
	u := UUID{}
	for i := 0; i < 16; i++ {
		u[i] = u1[i] | u2[i]
	}
	return u
}

// Returns true if u1 and u2 equals, otherwise returns false.
func Equal(u1 UUID, u2 UUID) bool {
	return bytes.Equal(u1[:], u2[:])
}

// Returns algorithm version used to generate UUID.
func (u UUID) Version() uint {
	return uint(u[6] >> 4)
}

// Returns UUID layout variant.
func (u UUID) Variant() uint {
	switch {
	case (u[8] & 0x80) == 0x00:
		return VariantNCS
	case (u[8]&0xc0)|0x80 == 0x80:
		return VariantRFC4122
	case (u[8]&0xe0)|0xc0 == 0xc0:
		return VariantMicrosoft
	}
	return VariantFuture
}

// Returns canonical string representation of UUID:
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
func (u UUID) String() string {
	return fmt.Sprintf("%x-%x-%x-%x-%x",
		u[:4], u[4:6], u[6:8], u[8:10], u[10:])
}

// Sets version bits.
func (u *UUID) SetVersion(v byte) {
	u[6] = (u[6] & 0x0f) | (v << 4)
}

// Sets variant bits as described in RFC 4122.
func (u *UUID) SetVariant() {
	u[8] = (u[8] & 0xbf) | 0x80
}

// Returns UUID epoch timestamp
func getTimestamp() uint64 {
	timeNow := epochStart + epochFunc()
	// Clock changed backwards since last UUID generation.
	// Should increase clock sequence.
	if timeNow <= lastTime {
		clockSequence++
	}
	lastTime = timeNow
	return timeNow
}

// Returns UUID based on current timestamp and MAC address.
func NewV1() UUID {
	u := UUID{}

	timeNow := getTimestamp()

	binary.BigEndian.PutUint32(u[0:], uint32(timeNow))
	binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
	binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
	binary.BigEndian.PutUint16(u[8:], clockSequence)

	copy(u[10:], hardwareAddr[:])

	u.SetVersion(1)
	u.SetVariant()

	return u
}

// Returns DCE Security UUID based on POSIX UID/GID.
func NewV2(domain byte) UUID {
	u := UUID{}

	switch domain {
	case DomainPerson:
		binary.BigEndian.PutUint32(u[0:], posixUID)
	case DomainGroup:
		binary.BigEndian.PutUint32(u[0:], posixGID)
	}

	timeNow := getTimestamp()

	binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
	binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
	binary.BigEndian.PutUint16(u[8:], clockSequence)
	u[9] = domain
	copy(u[10:], hardwareAddr[:])
	u.SetVersion(2)
	u.SetVariant()

	return u
}

// Returns UUID based on MD5 hash of namespace UUID and name.
func NewV3(ns UUID, name string) UUID {
	u := newFromHash(md5.New(), ns, name)
	u.SetVersion(3)
	u.SetVariant()

	return u
}

// Returns random generated UUID.
func NewV4() UUID {
	u := UUID{}
	rand.Read(u[:])
	u.SetVersion(4)
	u.SetVariant()

	return u
}

// Returns UUID based on SHA-1 hash of namespace UUID and name.
func NewV5(ns UUID, name string) UUID {
	u := newFromHash(sha1.New(), ns, name)
	u.SetVersion(5)
	u.SetVariant()

	return u
}

// Returns UUID based on hashing of namespace UUID and name.
func newFromHash(h hash.Hash, ns UUID, name string) UUID {
	u := UUID{}
	h.Write(ns[:])
	h.Write([]byte(name))
	copy(u[:], h.Sum(nil))

	return u
}
<|endoftext|>


<commit_before>package qselect

import (
	"regexp"
	"strings"
	"ddb/structs/types"
)

type ParseWhereCondFunc func(q string) (query string, whereCond types.WhereCond, result bool)

func ParseWhere(q string) (query string, where types.Where, result bool) {

	where = types.Where{}

	if _, q, result = parseByRegexp(rewhere, q); !result {
		return q, where, result
	}

	funcs := []ParseWhereCondFunc{
		ParseWhereCond,
	}

	result = false

	for {
		r := true

		if result && !reandor.MatchString(q) {
			break
		}

		q = string(reandor.ReplaceAll([]byte(q), []byte{}))

		for _, f := range funcs {
			var wc types.WhereCond

			if q, wc, r = f(q); !r {
				continue
			}

			where = append(where, wc)

			result = true
			break
		}

		if !r {
			break
		}
	}

	return q, where, result
}

func ParseWhereOperand(q string) (query string, operand string, result bool) {
	query = q

	operands := []*regexp.Regexp{
		reconstint,
		reconststr,
		refunc,
		recolumn,
		reenum,
	}

	for _, o := range operands {
		if o.MatchString(q) {
			operand = strings.Trim(o.FindString(q), " ")
			query = string(o.ReplaceAll([]byte(q), []byte{}))
			result = true

			break
		}
	}

	return query, operand, result
}

func ParseWhereCond(q string) (query string, whereCond types.WhereCond, result bool) {

	query = q

	if q, whereCond.OperandA, result = ParseWhereOperand(q); !result {
		return query, whereCond, result
	}

	recompare := regexp.MustCompile(`^(?i)\s*(<>|\<|\>|=|!=|\s*in\s*){1}\s*`)

	if recompare.MatchString(q) {
		whereCond.Compartion = strings.Trim(recompare.FindString(q), " ")
		q = string(recompare.ReplaceAll([]byte(q), []byte{}))
	} else {
		return query, whereCond, false
	}

	if q, whereCond.OperandB, result = ParseWhereOperand(q); !result {
		return query, whereCond, result
	}

	return q, whereCond, result
}
<commit_msg>search by raw columns<commit_after>package qselect

import (
	"regexp"
	"strings"
	"ddb/structs/types"
)

type ParseWhereCondFunc func(q string) (query string, whereCond types.WhereCond, result bool)

func ParseWhere(q string) (query string, where types.Where, result bool) {

	where = types.Where{}

	if _, q, result = parseByRegexp(rewhere, q); !result {
		return q, where, result
	}

	funcs := []ParseWhereCondFunc{
		ParseWhereCond,
	}

	result = false

	for {
		r := true

		if result && !reandor.MatchString(q) {
			break
		}

		q = string(reandor.ReplaceAll([]byte(q), []byte{}))

		for _, f := range funcs {
			var wc types.WhereCond

			if q, wc, r = f(q); !r {
				continue
			}

			where = append(where, wc)

			result = true
			break
		}

		if !r {
			break
		}
	}

	return q, where, result
}

func ParseWhereOperand(q string) (query string, operand string, result bool) {
	query = q

	operands := []*regexp.Regexp{
		reconstint,
		reconststr,
		refunc,
		recolumn,
		reenum,
	}

	for _, o := range operands {
		if o.MatchString(q) {
			operand = strings.Trim(o.FindString(q), " ")
			query = string(o.ReplaceAll([]byte(q), []byte{}))
			result = true

			break
		}
	}

	return query, operand, result
}

func ParseWhereCond(q string) (query string, whereCond types.WhereCond, result bool) {

	query = q

	if q, whereCond.OperandA, result = ParseWhereOperand(q); !result {
		return query, whereCond, result
	}

	recompare := regexp.MustCompile(`^(?i)\s*(<>|<|>|=|!=|\s*in\s*){1}\s*`)

	if recompare.MatchString(q) {
		whereCond.Compartion = strings.Trim(recompare.FindString(q), " ")
		q = string(recompare.ReplaceAll([]byte(q), []byte{}))
	} else {
		return query, whereCond, false
	}

	if q, whereCond.OperandB, result = ParseWhereOperand(q); !result {
		return query, whereCond, result
	}

	return q, whereCond, result
}
<|endoftext|>


<commit_before>// Package vago

package vago

/*
#cgo pkg-config: varnishapi
#cgo LDFLAGS: -lvarnishapi -lm
#include <sys/types.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <vapi/vsc.h>
#include <vapi/vsm.h>
#include <vapi/vsl.h>

int listCallback(void *priv, struct VSC_point *);
int dispatchCallback(struct VSL_data *vsl, struct VSL_transaction **trans, void *priv);
*/
import "C"

import (
	"encoding/binary"
	"errors"
	"fmt"
	"time"
	"unsafe"
)

const (
	// Grouping mode
	RAW  = C.VSL_g_raw
	VXID = C.VSL_g_vxid
	REQ  = C.VSL_g_request
	SESS = C.VSL_g_session

	lenmask       = 0xffff
	clientmarker  = uint32(1) << 30
	backendmarker = uint32(1) << 31
	identmask     = ^(uint32(3) << 30)
)

var ptrHandles *handleList

func init() {
	ptrHandles = newHandle()
}

// A Varnish struct represents a handler for Varnish Shared Memory and
// Varnish Shared Log.
type Varnish struct {
	vsm    *C.struct_VSM_data
	vsl    *C.struct_VSL_data
	vslq   *C.struct_VSLQ
	cursor *C.struct_VSL_cursor
}

// Open opens a Varnish Shared Memory file. If successful, returns a new
// Varnish.
func Open(path string) (*Varnish, error) {
	v := Varnish{}
	v.vsm = C.VSM_New()
	if v.vsm == nil {
		return nil, errors.New(C.GoString(C.VSM_Error(v.vsm)))
	}
	if path != "" {
		cs := C.CString(path)
		defer C.free(unsafe.Pointer(cs))
		if C.VSM_n_Arg(v.vsm, cs) != 1 {
			return nil, errors.New(C.GoString(C.VSM_Error(v.vsm)))
		}
	}
	if C.VSM_Open(v.vsm) < 0 {
		return nil, errors.New(C.GoString(C.VSM_Error(v.vsm)))
	}
	return &v, nil
}

// Close closes and unmaps the Varnish Shared Memory.
func (v *Varnish) Close() {
	if v.vslq != nil {
		C.VSLQ_Delete(&v.vslq)
	}
	if v.vsl != nil {
		C.VSL_Delete(v.vsl)
	}
	if v.vsm != nil {
		C.VSM_Delete(v.vsm)
	}
}

// LogCallback defines a callback function.
// It's used by Log.
type LogCallback func(vxid uint32, tag, _type, data string) int

// Log calls the given callback for any transactions matching the query
// and grouping.
func (v *Varnish) Log(query string, grouping uint32, logCallback LogCallback) error {
	v.vsl = C.VSL_New()
	for {
		v.cursor = C.VSL_CursorVSM(v.vsl, v.vsm, 1)
		if v.cursor != nil {
			break
		}
	}
	if grouping < 0 || grouping > 4 {
		grouping = VXID
	}
	if query != "" {
		cs := C.CString(query)
		defer C.free(unsafe.Pointer(cs))
		v.vslq = C.VSLQ_New(v.vsl, nil, grouping, cs)
	} else {
		v.vslq = C.VSLQ_New(v.vsl, nil, grouping, nil)
	}
	if v.vslq == nil {
		return errors.New(C.GoString(C.VSL_Error(v.vsl)))
	}
	C.VSLQ_SetCursor((*v).vslq, &v.cursor)
	for {
		i := C.VSLQ_Dispatch(v.vslq,
			(*C.VSLQ_dispatch_f)(unsafe.Pointer(C.dispatchCallback)),
			unsafe.Pointer(&logCallback))
		if i == 1 {
			continue
		}
		if i == 0 {
			time.Sleep(1000)
			continue
		}
		if i == -1 {
			break
		}
	}
	return nil
}

// dispatchCallback walks through the transaction and calls a function of
// type LogCallback.
//export dispatchCallback
func dispatchCallback(vsl *C.struct_VSL_data, pt **C.struct_VSL_transaction, logCallback unsafe.Pointer) C.int {
	var tx = uintptr(unsafe.Pointer(pt))
	for {
		if tx == 0 {
			break
		}
		t := ((**C.struct_VSL_transaction)(unsafe.Pointer(tx)))
		if *t == nil {
			break
		}
		for {
			i := C.VSL_Next((*t).c)
			if i < 0 {
				return i
			}
			if i == 0 {
				break
			}
			if C.VSL_Match(vsl, (*t).c) == 0 {
				continue
			}

			// ptr is an uint32_t pointer array, we use GoBytes to
			// back it in a Go byte slice to retrieve its 32 bits
			// elements.
			b := C.GoBytes(unsafe.Pointer((*t).c.rec.ptr), 8)
			s := make([]uint32, 2)
			for i := range s {
				s[i] = uint32(binary.LittleEndian.Uint32(b[i*4 : (i+1)*4]))
			}
			tag := C.GoString(C.VSL_tags[s[0]>>24])
			vxid := s[1] & identmask
			_type := "-"
			if s[1]&(clientmarker) != 0 {
				_type = "c"
			} else if s[1]&(backendmarker) != 0 {
				_type = "b"
			}
			lenght := C.int(s[0] & lenmask)
			u32 := cui32tosl((*t).c.rec.ptr, (lenght+2)*4)
			data := ui32tostr(&u32[2], lenght)
			ret := (*(*LogCallback)(logCallback))(vxid, tag, _type, data)
			if ret != 0 {
				return C.int(ret)
			}
		}
		tx += unsafe.Sizeof(t)
	}
	return 0
}

// Stats returns a map with all stat counters and their values.
func (v *Varnish) Stats() map[string]uint64 {
	items := make(map[string]uint64)
	handle := ptrHandles.track(items)
	defer ptrHandles.untrack(handle)
	C.VSC_Iter(v.vsm, nil,
		(*C.VSC_iter_f)(unsafe.Pointer(C.listCallback)),
		handle)
	return items
}

// Stat takes a counter and returns its value.
func (v *Varnish) Stat(s string) uint64 {
	stats := v.Stats()
	return stats[s]
}

//export listCallback
func listCallback(handle unsafe.Pointer, pt *C.struct_VSC_point) C.int {
	priv := ptrHandles.get(handle)
	var name string
	if pt == nil || priv == nil {
		return 1
	}
	_type := C.GoString(&pt.section.fantom._type[0])
	ident := C.GoString(&pt.section.fantom.ident[0])
	field := C.GoString(pt.desc.name)
	value := *(*uint64)(unsafe.Pointer(pt.ptr))
	s := fmt.Sprint(_type)
	if ident != "" {
		name = fmt.Sprint(s, ".", ident, ".", field)
	} else {
		name = fmt.Sprint(s, ".", field)
	}
	items, ok := priv.(map[string]uint64)
	if !ok {
		return 1
	}
	items[name] = value
	return 0
}

// Convert uint32 to string
func ui32tostr(val *uint32, lenght C.int) string {
	return C.GoStringN((*C.char)(unsafe.Pointer(val)), lenght)
}

// Convert C.uint32_t to slice of uint32
func cui32tosl(ptr *C.uint32_t, lenght C.int) []uint32 {
	b := C.GoBytes(unsafe.Pointer(ptr), lenght)
	s := make([]uint32, lenght/4)
	for i := range s {
		s[i] = uint32(binary.LittleEndian.Uint32(b[i*4 : (i+1)*4]))
	}
	return s
}
<commit_msg>Drop VSLQ_SetCursor()<commit_after>// Package vago

package vago

/*
#cgo pkg-config: varnishapi
#cgo LDFLAGS: -lvarnishapi -lm
#include <sys/types.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <vapi/vsc.h>
#include <vapi/vsm.h>
#include <vapi/vsl.h>

int listCallback(void *priv, struct VSC_point *);
int dispatchCallback(struct VSL_data *vsl, struct VSL_transaction **trans, void *priv);
*/
import "C"

import (
	"encoding/binary"
	"errors"
	"fmt"
	"time"
	"unsafe"
)

const (
	// Grouping mode
	RAW  = C.VSL_g_raw
	VXID = C.VSL_g_vxid
	REQ  = C.VSL_g_request
	SESS = C.VSL_g_session

	lenmask       = 0xffff
	clientmarker  = uint32(1) << 30
	backendmarker = uint32(1) << 31
	identmask     = ^(uint32(3) << 30)
)

var ptrHandles *handleList

func init() {
	ptrHandles = newHandle()
}

// A Varnish struct represents a handler for Varnish Shared Memory and
// Varnish Shared Log.
type Varnish struct {
	vsm    *C.struct_VSM_data
	vsl    *C.struct_VSL_data
	vslq   *C.struct_VSLQ
	cursor *C.struct_VSL_cursor
}

// Open opens a Varnish Shared Memory file. If successful, returns a new
// Varnish.
func Open(path string) (*Varnish, error) {
	v := Varnish{}
	v.vsm = C.VSM_New()
	if v.vsm == nil {
		return nil, errors.New(C.GoString(C.VSM_Error(v.vsm)))
	}
	if path != "" {
		cs := C.CString(path)
		defer C.free(unsafe.Pointer(cs))
		if C.VSM_n_Arg(v.vsm, cs) != 1 {
			return nil, errors.New(C.GoString(C.VSM_Error(v.vsm)))
		}
	}
	if C.VSM_Open(v.vsm) < 0 {
		return nil, errors.New(C.GoString(C.VSM_Error(v.vsm)))
	}
	return &v, nil
}

// Close closes and unmaps the Varnish Shared Memory.
func (v *Varnish) Close() {
	if v.vslq != nil {
		C.VSLQ_Delete(&v.vslq)
	}
	if v.vsl != nil {
		C.VSL_Delete(v.vsl)
	}
	if v.vsm != nil {
		C.VSM_Delete(v.vsm)
	}
}

// LogCallback defines a callback function.
// It's used by Log.
type LogCallback func(vxid uint32, tag, _type, data string) int

// Log calls the given callback for any transactions matching the query
// and grouping.
func (v *Varnish) Log(query string, grouping uint32, logCallback LogCallback) error {
	v.vsl = C.VSL_New()
	for {
		v.cursor = C.VSL_CursorVSM(v.vsl, v.vsm, 1)
		if v.cursor != nil {
			break
		}
	}
	if grouping < 0 || grouping > 4 {
		grouping = VXID
	}
	if query != "" {
		cs := C.CString(query)
		defer C.free(unsafe.Pointer(cs))
		v.vslq = C.VSLQ_New(v.vsl, &v.cursor, grouping, cs)
	} else {
		v.vslq = C.VSLQ_New(v.vsl, &v.cursor, grouping, nil)
	}
	if v.vslq == nil {
		return errors.New(C.GoString(C.VSL_Error(v.vsl)))
	}
	for {
		i := C.VSLQ_Dispatch(v.vslq,
			(*C.VSLQ_dispatch_f)(unsafe.Pointer(C.dispatchCallback)),
			unsafe.Pointer(&logCallback))
		if i == 1 {
			continue
		}
		if i == 0 {
			time.Sleep(1000)
			continue
		}
		if i == -1 {
			break
		}
	}
	return nil
}

// dispatchCallback walks through the transaction and calls a function of
// type LogCallback.
//export dispatchCallback
func dispatchCallback(vsl *C.struct_VSL_data, pt **C.struct_VSL_transaction, logCallback unsafe.Pointer) C.int {
	var tx = uintptr(unsafe.Pointer(pt))
	for {
		if tx == 0 {
			break
		}
		t := ((**C.struct_VSL_transaction)(unsafe.Pointer(tx)))
		if *t == nil {
			break
		}
		for {
			i := C.VSL_Next((*t).c)
			if i < 0 {
				return i
			}
			if i == 0 {
				break
			}
			if C.VSL_Match(vsl, (*t).c) == 0 {
				continue
			}

			// ptr is an uint32_t pointer array, we use GoBytes to
			// back it in a Go byte slice to retrieve its 32 bits
			// elements.
			b := C.GoBytes(unsafe.Pointer((*t).c.rec.ptr), 8)
			s := make([]uint32, 2)
			for i := range s {
				s[i] = uint32(binary.LittleEndian.Uint32(b[i*4 : (i+1)*4]))
			}
			tag := C.GoString(C.VSL_tags[s[0]>>24])
			vxid := s[1] & identmask
			_type := "-"
			if s[1]&(clientmarker) != 0 {
				_type = "c"
			} else if s[1]&(backendmarker) != 0 {
				_type = "b"
			}
			lenght := C.int(s[0] & lenmask)
			u32 := cui32tosl((*t).c.rec.ptr, (lenght+2)*4)
			data := ui32tostr(&u32[2], lenght)
			ret := (*(*LogCallback)(logCallback))(vxid, tag, _type, data)
			if ret != 0 {
				return C.int(ret)
			}
		}
		tx += unsafe.Sizeof(t)
	}
	return 0
}

// Stats returns a map with all stat counters and their values.
func (v *Varnish) Stats() map[string]uint64 {
	items := make(map[string]uint64)
	handle := ptrHandles.track(items)
	defer ptrHandles.untrack(handle)
	C.VSC_Iter(v.vsm, nil,
		(*C.VSC_iter_f)(unsafe.Pointer(C.listCallback)),
		handle)
	return items
}

// Stat takes a counter and returns its value.
func (v *Varnish) Stat(s string) uint64 {
	stats := v.Stats()
	return stats[s]
}

//export listCallback
func listCallback(handle unsafe.Pointer, pt *C.struct_VSC_point) C.int {
	priv := ptrHandles.get(handle)
	var name string
	if pt == nil || priv == nil {
		return 1
	}
	_type := C.GoString(&pt.section.fantom._type[0])
	ident := C.GoString(&pt.section.fantom.ident[0])
	field := C.GoString(pt.desc.name)
	value := *(*uint64)(unsafe.Pointer(pt.ptr))
	s := fmt.Sprint(_type)
	if ident != "" {
		name = fmt.Sprint(s, ".", ident, ".", field)
	} else {
		name = fmt.Sprint(s, ".", field)
	}
	items, ok := priv.(map[string]uint64)
	if !ok {
		return 1
	}
	items[name] = value
	return 0
}

// Convert uint32 to string
func ui32tostr(val *uint32, lenght C.int) string {
	return C.GoStringN((*C.char)(unsafe.Pointer(val)), lenght)
}

// Convert C.uint32_t to slice of uint32
func cui32tosl(ptr *C.uint32_t, lenght C.int) []uint32 {
	b := C.GoBytes(unsafe.Pointer(ptr), lenght)
	s := make([]uint32, lenght/4)
	for i := range s {
		s[i] = uint32(binary.LittleEndian.Uint32(b[i*4 : (i+1)*4]))
	}
	return s
}
<|endoftext|>


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

package nvimutil

import (
	"testing"

	"github.com/neovim/go-client/nvim"
)

func TestTerminal_getWindowSize(t *testing.T) {
	v := TestNvim(t)
	type fields struct {
		v *nvim.Nvim
	}
	type args struct {
		cfg int64
		fn  func(nvim.Window) (int, error)
	}
	tests := []struct {
		name   string
		fields fields
		args   args
		want   int
	}{
		{
			name: "Use config",
			fields: fields{
				v: v,
			},
			args: args{
				cfg: 120,
				fn:  v.WindowWidth,
			},
			want: 120,
		},
		{
			name: "Use (WindowWidth / 3 )",
			fields: fields{
				v: v,
			},
			args: args{
				cfg: 0,
				fn:  v.WindowWidth,
			},
			// default embedded Nvim Window width is 80.
			want: 26,
		},
		{
			name: "Use (WindowHeight / 3 )",
			fields: fields{
				v: v,
			},
			args: args{
				cfg: 0,
				fn:  v.WindowHeight,
			},
			// default embedded Nvim Window height is 22.
			want: 7,
		},
	}
	for _, tt := range tests {
		tt := tt
		t.Run(tt.name, func(t *testing.T) {
			t.Parallel()
			term := &Terminal{
				v: tt.fields.v,
			}
			if got := term.getWindowSize(tt.args.cfg, tt.args.fn); got != tt.want {
				t.Errorf("Terminal.getWindowSize(%v, %v) = %v, want %v", tt.args.cfg, tt.args.fn, got, tt.want)
			}
		})
	}
}
<commit_msg>test/nvimutil/terminal: rename variables<commit_after>// Copyright 2016 The nvim-go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package nvimutil

import (
	"testing"

	"github.com/neovim/go-client/nvim"
)

func TestTerminal_getWindowSize(t *testing.T) {
	n := TestNvim(t)
	type fields struct {
		Nvim *nvim.Nvim
	}
	type args struct {
		cfg int64
		f   func(nvim.Window) (int, error)
	}
	tests := []struct {
		name   string
		fields fields
		args   args
		want   int
	}{
		{
			name: "Use config",
			fields: fields{
				Nvim: n,
			},
			args: args{
				cfg: 120,
				f:   n.WindowWidth,
			},
			want: 120,
		},
		{
			name: "Use (WindowWidth / 3 )",
			fields: fields{
				Nvim: n,
			},
			args: args{
				cfg: 0,
				f:   n.WindowWidth,
			},
			// default embedded Nvim Window width is 80.
			want: 26,
		},
		{
			name: "Use (WindowHeight / 3 )",
			fields: fields{
				Nvim: n,
			},
			args: args{
				cfg: 0,
				f:   n.WindowHeight,
			},
			// default embedded Nvim Window height is 22.
			want: 7,
		},
	}
	for _, tt := range tests {
		tt := tt
		t.Run(tt.name, func(t *testing.T) {
			t.Parallel()
			term := &Terminal{
				Nvim: tt.fields.Nvim,
			}
			if got := term.getSplitWindowSize(tt.args.cfg, tt.args.f); got != tt.want {
				t.Errorf("Terminal.getWindowSize(%v, %v) = %v, want %v", tt.args.cfg, tt.args.f, got, tt.want)
			}
		})
	}
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors All rights reserved.

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

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

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

package simulator

import (
	"flag"
	"fmt"
	"math"
	"math/rand"
	"time"

	kube_api "k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/resource"
	kube_client "k8s.io/kubernetes/pkg/client/unversioned"
	cmd "k8s.io/kubernetes/pkg/kubectl/cmd"
	"k8s.io/kubernetes/plugin/pkg/scheduler/schedulercache"

	"github.com/golang/glog"
)

var (
	skipNodesWithSystemPods = flag.Bool("skip-nodes-with-system-pods", true,
		"If true cluster autoscaler will never delete nodes with pods from kube-system (except for DeamonSet "+
			"or mirror pods)")
	skipNodesWithLocalStorage = flag.Bool("skip-nodes-with-local-storage", true,
		"If true cluster autoscaler will never delete nodes with pods with local storage, e.g. EmptyDir or HostPath")
)

// FindNodesToRemove finds nodes that can be removed. Returns also an information about good
// rescheduling location for each of the pods.
func FindNodesToRemove(candidates []*kube_api.Node, allNodes []*kube_api.Node, pods []*kube_api.Pod,
	client *kube_client.Client, predicateChecker *PredicateChecker, maxCount int,
	fastCheck bool, oldHints map[string]string, usageTracker *UsageTracker,
	timestamp time.Time) (nodesToRemove []*kube_api.Node, podReschedulingHints map[string]string, finalError error) {

	nodeNameToNodeInfo := schedulercache.CreateNodeNameToInfoMap(pods)
	for _, node := range allNodes {
		if nodeInfo, found := nodeNameToNodeInfo[node.Name]; found {
			nodeInfo.SetNode(node)
		}
	}
	result := make([]*kube_api.Node, 0)

	evaluationType := "Detailed evaluation"
	if fastCheck {
		evaluationType = "Fast evaluation"
	}
	newHints := make(map[string]string, len(oldHints))

candidateloop:
	for _, node := range candidates {
		glog.V(2).Infof("%s: %s for removal", evaluationType, node.Name)

		var podsToRemove []*kube_api.Pod
		var err error

		if fastCheck {
			if nodeInfo, found := nodeNameToNodeInfo[node.Name]; found {
				podsToRemove, err = FastGetPodsToMove(nodeInfo, false, *skipNodesWithSystemPods, *skipNodesWithLocalStorage)
				if err != nil {
					glog.V(2).Infof("%s: node %s cannot be removed: %v", evaluationType, node.Name, err)
					continue candidateloop
				}
			} else {
				glog.V(2).Infof("%s: nodeInfo for %s not found", evaluationType, node.Name)
				continue candidateloop
			}
		} else {
			drainResult, _, _, err := cmd.GetPodsForDeletionOnNodeDrain(client, node.Name,
				kube_api.Codecs.UniversalDecoder(), false, true)

			if err != nil {
				glog.V(2).Infof("%s: node %s cannot be removed: %v", evaluationType, node.Name, err)
				continue candidateloop
			}
			podsToRemove = make([]*kube_api.Pod, 0, len(drainResult))
			for i := range drainResult {
				podsToRemove = append(podsToRemove, &drainResult[i])
			}
		}
		findProblems := findPlaceFor(node.Name, podsToRemove, allNodes, nodeNameToNodeInfo, predicateChecker, oldHints, newHints,
			usageTracker, timestamp)

		if findProblems == nil {
			result = append(result, node)
			glog.V(2).Infof("%s: node %s may be removed", evaluationType, node.Name)
			if len(result) >= maxCount {
				break candidateloop
			}
		} else {
			glog.V(2).Infof("%s: node %s is not suitable for removal %v", evaluationType, node.Name, err)
		}
	}
	return result, newHints, nil
}

// CalculateUtilization calculates utilization of a node, defined as total amount of requested resources divided by capacity.
func CalculateUtilization(node *kube_api.Node, nodeInfo *schedulercache.NodeInfo) (float64, error) {
	cpu, err := calculateUtilizationOfResource(node, nodeInfo, kube_api.ResourceCPU)
	if err != nil {
		return 0, err
	}
	mem, err := calculateUtilizationOfResource(node, nodeInfo, kube_api.ResourceMemory)
	if err != nil {
		return 0, err
	}
	return math.Max(cpu, mem), nil
}

func calculateUtilizationOfResource(node *kube_api.Node, nodeInfo *schedulercache.NodeInfo, resourceName kube_api.ResourceName) (float64, error) {
	nodeCapacity, found := node.Status.Capacity[resourceName]
	if !found {
		return 0, fmt.Errorf("Failed to get %v from %s", resourceName, node.Name)
	}
	if nodeCapacity.MilliValue() == 0 {
		return 0, fmt.Errorf("%v is 0 at %s", resourceName, node.Name)
	}
	podsRequest := resource.MustParse("0")
	for _, pod := range nodeInfo.Pods() {
		for _, container := range pod.Spec.Containers {
			if resourceValue, found := container.Resources.Requests[resourceName]; found {
				podsRequest.Add(resourceValue)
			}
		}
	}
	return float64(podsRequest.MilliValue()) / float64(nodeCapacity.MilliValue()), nil
}

// TODO: We don't need to pass list of nodes here as they are already available in nodeInfos.
func findPlaceFor(removedNode string, pods []*kube_api.Pod, nodes []*kube_api.Node, nodeInfos map[string]*schedulercache.NodeInfo,
	predicateChecker *PredicateChecker, oldHints map[string]string, newHints map[string]string, usageTracker *UsageTracker,
	timestamp time.Time) error {

	newNodeInfos := make(map[string]*schedulercache.NodeInfo)

	podKey := func(pod *kube_api.Pod) string {
		return fmt.Sprintf("%s/%s", pod.Namespace, pod.Name)
	}

	tryNodeForPod := func(nodename string, pod *kube_api.Pod) bool {
		nodeInfo, found := newNodeInfos[nodename]
		if !found {
			nodeInfo, found = nodeInfos[nodename]
		}
		if found {
			nodeInfo.Node().Status.Allocatable = nodeInfo.Node().Status.Capacity
			err := predicateChecker.CheckPredicates(pod, nodeInfo)
			glog.V(4).Infof("Evaluation %s for %s/%s -> %v", nodename, pod.Namespace, pod.Name, err)
			if err == nil {
				// TODO(mwielgus): Optimize it.
				podsOnNode := nodeInfo.Pods()
				podsOnNode = append(podsOnNode, pod)
				newNodeInfo := schedulercache.NewNodeInfo(podsOnNode...)
				newNodeInfo.SetNode(nodeInfo.Node())
				newNodeInfos[nodename] = newNodeInfo
				newHints[podKey(pod)] = nodename
				return true
			}
		}
		return false
	}

	// TODO: come up with a better semi-random semi-utilization sorted
	// layout.
	shuffledNodes := shuffleNodes(nodes)

	for _, podptr := range pods {
		newpod := *podptr
		newpod.Spec.NodeName = ""
		pod := &newpod

		foundPlace := false
		targetNode := ""

		glog.V(4).Infof("Looking for place for %s/%s", pod.Namespace, pod.Name)

		hintedNode, hasHint := oldHints[podKey(pod)]
		if hasHint {
			if hintedNode != removedNode && tryNodeForPod(hintedNode, pod) {
				foundPlace = true
				targetNode = hintedNode
			}
		}
		if !foundPlace {
			for _, node := range shuffledNodes {
				if node.Name == removedNode {
					continue
				}
				if tryNodeForPod(node.Name, pod) {
					foundPlace = true
					targetNode = node.Name
					break
				}
			}
			if !foundPlace {
				return fmt.Errorf("failed to find place for %s", podKey)
			}
		}

		usageTracker.RegisterUsage(removedNode, targetNode, timestamp)
	}
	return nil
}

func shuffleNodes(nodes []*kube_api.Node) []*kube_api.Node {
	result := make([]*kube_api.Node, len(nodes))
	for i := range nodes {
		result[i] = nodes[i]
	}
	for i := range result {
		j := rand.Intn(len(result))
		result[i], result[j] = result[j], result[i]
	}
	return result
}
<commit_msg>Cluster-autoscaler: skip nodeinfos with nil nodes<commit_after>/*
Copyright 2016 The Kubernetes Authors All rights reserved.

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

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

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

package simulator

import (
	"flag"
	"fmt"
	"math"
	"math/rand"
	"time"

	kube_api "k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/resource"
	kube_client "k8s.io/kubernetes/pkg/client/unversioned"
	cmd "k8s.io/kubernetes/pkg/kubectl/cmd"
	"k8s.io/kubernetes/plugin/pkg/scheduler/schedulercache"

	"github.com/golang/glog"
)

var (
	skipNodesWithSystemPods = flag.Bool("skip-nodes-with-system-pods", true,
		"If true cluster autoscaler will never delete nodes with pods from kube-system (except for DeamonSet "+
			"or mirror pods)")
	skipNodesWithLocalStorage = flag.Bool("skip-nodes-with-local-storage", true,
		"If true cluster autoscaler will never delete nodes with pods with local storage, e.g. EmptyDir or HostPath")
)

// FindNodesToRemove finds nodes that can be removed. Returns also an information about good
// rescheduling location for each of the pods.
func FindNodesToRemove(candidates []*kube_api.Node, allNodes []*kube_api.Node, pods []*kube_api.Pod,
	client *kube_client.Client, predicateChecker *PredicateChecker, maxCount int,
	fastCheck bool, oldHints map[string]string, usageTracker *UsageTracker,
	timestamp time.Time) (nodesToRemove []*kube_api.Node, podReschedulingHints map[string]string, finalError error) {

	nodeNameToNodeInfo := schedulercache.CreateNodeNameToInfoMap(pods)
	for _, node := range allNodes {
		if nodeInfo, found := nodeNameToNodeInfo[node.Name]; found {
			nodeInfo.SetNode(node)
		}
	}
	result := make([]*kube_api.Node, 0)

	evaluationType := "Detailed evaluation"
	if fastCheck {
		evaluationType = "Fast evaluation"
	}
	newHints := make(map[string]string, len(oldHints))

candidateloop:
	for _, node := range candidates {
		glog.V(2).Infof("%s: %s for removal", evaluationType, node.Name)

		var podsToRemove []*kube_api.Pod
		var err error

		if fastCheck {
			if nodeInfo, found := nodeNameToNodeInfo[node.Name]; found {
				podsToRemove, err = FastGetPodsToMove(nodeInfo, false, *skipNodesWithSystemPods, *skipNodesWithLocalStorage)
				if err != nil {
					glog.V(2).Infof("%s: node %s cannot be removed: %v", evaluationType, node.Name, err)
					continue candidateloop
				}
			} else {
				glog.V(2).Infof("%s: nodeInfo for %s not found", evaluationType, node.Name)
				continue candidateloop
			}
		} else {
			drainResult, _, _, err := cmd.GetPodsForDeletionOnNodeDrain(client, node.Name,
				kube_api.Codecs.UniversalDecoder(), false, true)

			if err != nil {
				glog.V(2).Infof("%s: node %s cannot be removed: %v", evaluationType, node.Name, err)
				continue candidateloop
			}
			podsToRemove = make([]*kube_api.Pod, 0, len(drainResult))
			for i := range drainResult {
				podsToRemove = append(podsToRemove, &drainResult[i])
			}
		}
		findProblems := findPlaceFor(node.Name, podsToRemove, allNodes, nodeNameToNodeInfo, predicateChecker, oldHints, newHints,
			usageTracker, timestamp)

		if findProblems == nil {
			result = append(result, node)
			glog.V(2).Infof("%s: node %s may be removed", evaluationType, node.Name)
			if len(result) >= maxCount {
				break candidateloop
			}
		} else {
			glog.V(2).Infof("%s: node %s is not suitable for removal %v", evaluationType, node.Name, err)
		}
	}
	return result, newHints, nil
}

// CalculateUtilization calculates utilization of a node, defined as total amount of requested resources divided by capacity.
func CalculateUtilization(node *kube_api.Node, nodeInfo *schedulercache.NodeInfo) (float64, error) {
	cpu, err := calculateUtilizationOfResource(node, nodeInfo, kube_api.ResourceCPU)
	if err != nil {
		return 0, err
	}
	mem, err := calculateUtilizationOfResource(node, nodeInfo, kube_api.ResourceMemory)
	if err != nil {
		return 0, err
	}
	return math.Max(cpu, mem), nil
}

func calculateUtilizationOfResource(node *kube_api.Node, nodeInfo *schedulercache.NodeInfo, resourceName kube_api.ResourceName) (float64, error) {
	nodeCapacity, found := node.Status.Capacity[resourceName]
	if !found {
		return 0, fmt.Errorf("Failed to get %v from %s", resourceName, node.Name)
	}
	if nodeCapacity.MilliValue() == 0 {
		return 0, fmt.Errorf("%v is 0 at %s", resourceName, node.Name)
	}
	podsRequest := resource.MustParse("0")
	for _, pod := range nodeInfo.Pods() {
		for _, container := range pod.Spec.Containers {
			if resourceValue, found := container.Resources.Requests[resourceName]; found {
				podsRequest.Add(resourceValue)
			}
		}
	}
	return float64(podsRequest.MilliValue()) / float64(nodeCapacity.MilliValue()), nil
}

// TODO: We don't need to pass list of nodes here as they are already available in nodeInfos.
func findPlaceFor(removedNode string, pods []*kube_api.Pod, nodes []*kube_api.Node, nodeInfos map[string]*schedulercache.NodeInfo,
	predicateChecker *PredicateChecker, oldHints map[string]string, newHints map[string]string, usageTracker *UsageTracker,
	timestamp time.Time) error {

	newNodeInfos := make(map[string]*schedulercache.NodeInfo)

	podKey := func(pod *kube_api.Pod) string {
		return fmt.Sprintf("%s/%s", pod.Namespace, pod.Name)
	}

	tryNodeForPod := func(nodename string, pod *kube_api.Pod) bool {
		nodeInfo, found := newNodeInfos[nodename]
		if !found {
			nodeInfo, found = nodeInfos[nodename]
		}
		if found {
			if nodeInfo.Node() == nil {
				// NodeInfo is generated based on pods. It is possible that node is removed from
				// an api server faster than the pod that were running on them. In such a case
				// we have to skip this nodeInfo. It should go away pretty soon.
				glog.Warningf("No node in nodeInfo %s -> %v", nodename, nodeInfo)
				return false
			}
			nodeInfo.Node().Status.Allocatable = nodeInfo.Node().Status.Capacity
			err := predicateChecker.CheckPredicates(pod, nodeInfo)
			glog.V(4).Infof("Evaluation %s for %s/%s -> %v", nodename, pod.Namespace, pod.Name, err)
			if err == nil {
				// TODO(mwielgus): Optimize it.
				podsOnNode := nodeInfo.Pods()
				podsOnNode = append(podsOnNode, pod)
				newNodeInfo := schedulercache.NewNodeInfo(podsOnNode...)
				newNodeInfo.SetNode(nodeInfo.Node())
				newNodeInfos[nodename] = newNodeInfo
				newHints[podKey(pod)] = nodename
				return true
			}
		}
		return false
	}

	// TODO: come up with a better semi-random semi-utilization sorted
	// layout.
	shuffledNodes := shuffleNodes(nodes)

	for _, podptr := range pods {
		newpod := *podptr
		newpod.Spec.NodeName = ""
		pod := &newpod

		foundPlace := false
		targetNode := ""

		glog.V(4).Infof("Looking for place for %s/%s", pod.Namespace, pod.Name)

		hintedNode, hasHint := oldHints[podKey(pod)]
		if hasHint {
			if hintedNode != removedNode && tryNodeForPod(hintedNode, pod) {
				foundPlace = true
				targetNode = hintedNode
			}
		}
		if !foundPlace {
			for _, node := range shuffledNodes {
				if node.Name == removedNode {
					continue
				}
				if tryNodeForPod(node.Name, pod) {
					foundPlace = true
					targetNode = node.Name
					break
				}
			}
			if !foundPlace {
				return fmt.Errorf("failed to find place for %s", podKey)
			}
		}

		usageTracker.RegisterUsage(removedNode, targetNode, timestamp)
	}
	return nil
}

func shuffleNodes(nodes []*kube_api.Node) []*kube_api.Node {
	result := make([]*kube_api.Node, len(nodes))
	for i := range nodes {
		result[i] = nodes[i]
	}
	for i := range result {
		j := rand.Intn(len(result))
		result[i], result[j] = result[j], result[i]
	}
	return result
}
<|endoftext|>