<commit_before>/*
Copyright IBM Corp. 2016 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 genesis

import (
	"fmt"
	"sync"

	"golang.org/x/net/context"

	"github.com/hyperledger/fabric/core/chaincode"
	"github.com/hyperledger/fabric/core/ledger"
	"github.com/hyperledger/fabric/protos"
	"github.com/op/go-logging"
)

var genesisLogger = logging.MustGetLogger("genesis")

var makeGenesisError error
var once sync.Once

// MakeGenesis creates the genesis block based on configuration in core.yaml
// and adds it to the blockchain.
func MakeGenesis() error {
	once.Do(func() {
		ledger, err := ledger.GetLedger()
		if err != nil {
			makeGenesisError = err
			return
		}

		var genesisBlockExists bool
		if ledger.GetBlockchainSize() == 0 {
			genesisLogger.Info("Creating genesis block.")
			ledger.BeginTxBatch(0)
		} else {
			genesisBlockExists = true
		}

		var genesisTransactions []*protos.Transaction

		defer func() {
			if !genesisBlockExists && makeGenesisError == nil {
				genesisLogger.Infof("Adding %d system chaincodes to the genesis block.", len(genesisTransactions))
				ledger.CommitTxBatch(0, genesisTransactions, nil, nil)
			}
		}()

		if getGenesis() == nil {
			genesisLogger.Info("No genesis block chaincodes defined.")
		} else {

			chaincodes, chaincodesOK := genesis["chaincodes"].(map[interface{}]interface{})
			if !chaincodesOK {
				genesisLogger.Info("No genesis block chaincodes defined.")
				ledger.CommitTxBatch(0, genesisTransactions, nil, nil)
				return
			}

			genesisLogger.Debugf("Genesis chaincodes are %s", chaincodes)

			for i := range chaincodes {
				name := i.(string)
				genesisLogger.Debugf("Chaincode %s", name)

				chaincode := chaincodes[name]
				chaincodeMap, chaincodeMapOK := chaincode.(map[interface{}]interface{})
				if !chaincodeMapOK {
					genesisLogger.Error("Invalid chaincode defined in genesis configuration:", chaincode)
					makeGenesisError = fmt.Errorf("Invalid chaincode defined in genesis configuration: %s", chaincode)
					return
				}

				path, pathOK := chaincodeMap["path"].(string)
				if !pathOK {
					genesisLogger.Error("Invalid chaincode URL defined in genesis configuration:", chaincodeMap["path"])
					makeGenesisError = fmt.Errorf("Invalid chaincode URL defined in genesis configuration: %s", chaincodeMap["path"])
					return
				}

				chaincodeType, chaincodeTypeOK := chaincodeMap["type"].(string)
				if !chaincodeTypeOK {
					genesisLogger.Error("Invalid chaincode type defined in genesis configuration:", chaincodeMap["type"])
					makeGenesisError = fmt.Errorf("Invalid chaincode type defined in genesis configuration: %s", chaincodeMap["type"])
					return
				}

				if chaincodeType == "" {
					chaincodeType = "GOLANG"
				}

				chaincodeID := &protos.ChaincodeID{Path: path, Name: name}

				genesisLogger.Debugf("Genesis chaincodeID %s", chaincodeID)

				constructorMap, constructorMapOK := chaincodeMap["constructor"].(map[interface{}]interface{})
				if !constructorMapOK {
					genesisLogger.Error("Invalid chaincode constructor defined in genesis configuration:", chaincodeMap["constructor"])
					makeGenesisError = fmt.Errorf("Invalid chaincode constructor defined in genesis configuration: %s", chaincodeMap["constructor"])
					return
				}

				var spec protos.ChaincodeSpec
				if constructorMap == nil {
					genesisLogger.Debug("Genesis chaincode has no constructor.")
					spec = protos.ChaincodeSpec{Type: protos.ChaincodeSpec_Type(protos.ChaincodeSpec_Type_value[chaincodeType]), ChaincodeID: chaincodeID}
				} else {

					_, ctorArgsOK := constructorMap["args"]
					if !ctorArgsOK {
						genesisLogger.Error("Invalid chaincode constructor args defined in genesis configuration:", constructorMap["args"])
						makeGenesisError = fmt.Errorf("Invalid chaincode constructor args defined in genesis configuration: %s", constructorMap["args"])
						return
					}

					ctorArgs, ctorArgsOK := constructorMap["args"].([]interface{})
					var ctorArgsStringArray []string
					if ctorArgsOK {
						genesisLogger.Debugf("Genesis chaincode constructor args %s", ctorArgs)
						for j := 0; j < len(ctorArgs); j++ {
							ctorArgsStringArray = append(ctorArgsStringArray, ctorArgs[j].(string))
						}
					}
					spec = protos.ChaincodeSpec{Type: protos.ChaincodeSpec_Type(protos.ChaincodeSpec_Type_value[chaincodeType]), ChaincodeID: chaincodeID, CtorMsg: &protos.ChaincodeInput{Args: ctorArgsStringArray}}
				}

				transaction, _, deployErr := DeployLocal(context.Background(), &spec, genesisBlockExists)
				if deployErr != nil {
					genesisLogger.Error("Error deploying chaincode for genesis block.", deployErr)
					makeGenesisError = deployErr
					return
				}

				genesisTransactions = append(genesisTransactions, transaction)

			} //for

		} //else
	})
	return makeGenesisError
}

//BuildLocal builds a given chaincode code
func BuildLocal(context context.Context, spec *protos.ChaincodeSpec) (*protos.ChaincodeDeploymentSpec, error) {
	genesisLogger.Debugf("Received build request for chaincode spec: %v", spec)
	var codePackageBytes []byte
	/*****  We will need this only when we support non-go SYSTEM chaincode ****
	if getMode() != chaincode.DevModeUserRunsChaincode {
		if err := core.CheckSpec(spec); err != nil {
			genesisLogger.Debug("check spec failed: %s", err)
			return nil, err
		}
		// Build the spec
		var err error
		codePackageBytes, err = container.GetChaincodePackageBytes(spec)
		if err != nil {
			genesisLogger.Error(fmt.Sprintf("Error getting VM: %s", err))
			return nil, err
		}
	}
	*********/
	chaincodeDeploymentSpec := &protos.ChaincodeDeploymentSpec{ExecEnv: protos.ChaincodeDeploymentSpec_SYSTEM, ChaincodeSpec: spec, CodePackage: codePackageBytes}
	return chaincodeDeploymentSpec, nil
}

// DeployLocal deploys the supplied chaincode image to the local peer
func DeployLocal(ctx context.Context, spec *protos.ChaincodeSpec, gbexists bool) (*protos.Transaction, []byte, error) {
	// First build and get the deployment spec
	chaincodeDeploymentSpec, err := BuildLocal(ctx, spec)

	if err != nil {
		genesisLogger.Error(fmt.Sprintf("Error deploying chaincode spec: %v\n\n error: %s", spec, err))
		return nil, nil, err
	}

	var transaction *protos.Transaction
	if gbexists {
		ledger, err := ledger.GetLedger()
		if err != nil {
			return nil, nil, fmt.Errorf("Failed to get handle to ledger (%s)", err)
		}
		transaction, err = ledger.GetTransactionByUUID(chaincodeDeploymentSpec.ChaincodeSpec.ChaincodeID.Name)
		if err != nil {
			genesisLogger.Warning(fmt.Sprintf("cannot get deployment transaction for %s - %s", chaincodeDeploymentSpec.ChaincodeSpec.ChaincodeID.Name, err))
			transaction = nil
		} else {
			genesisLogger.Debugf("deployment transaction for %s exists", chaincodeDeploymentSpec.ChaincodeSpec.ChaincodeID.Name)
		}
	}

	if transaction == nil {
		transaction, err = protos.NewChaincodeDeployTransaction(chaincodeDeploymentSpec, chaincodeDeploymentSpec.ChaincodeSpec.ChaincodeID.Name)
		if err != nil {
			return nil, nil, fmt.Errorf("Error deploying chaincode: %s ", err)
		}
	}

	//chaincode.NewChaincodeSupport(chaincode.DefaultChain, peer.GetPeerEndpoint, false, 120000)
	// The secHelper is set during creat ChaincodeSupport, so we don't need this step
	//ctx = context.WithValue(ctx, "security", secCxt)
	result, _, err := chaincode.Execute(ctx, chaincode.GetChain(chaincode.DefaultChain), transaction)
	return transaction, result, err
}
<commit_msg>fixing invalid log managing in genesis.go file<commit_after>/*
Copyright IBM Corp. 2016 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 genesis

import (
	"fmt"
	"sync"

	"golang.org/x/net/context"

	"github.com/hyperledger/fabric/core/chaincode"
	"github.com/hyperledger/fabric/core/ledger"
	"github.com/hyperledger/fabric/protos"
	"github.com/op/go-logging"
)

var genesisLogger = logging.MustGetLogger("genesis")

var makeGenesisError error
var once sync.Once

// MakeGenesis creates the genesis block based on configuration in core.yaml
// and adds it to the blockchain.
func MakeGenesis() error {
	once.Do(func() {
		ledger, err := ledger.GetLedger()
		if err != nil {
			makeGenesisError = err
			return
		}

		var genesisBlockExists bool
		if ledger.GetBlockchainSize() == 0 {
			genesisLogger.Info("Creating genesis block.")
			ledger.BeginTxBatch(0)
		} else {
			genesisBlockExists = true
		}

		var genesisTransactions []*protos.Transaction

		defer func() {
			if !genesisBlockExists && makeGenesisError == nil {
				genesisLogger.Infof("Adding %d system chaincodes to the genesis block.", len(genesisTransactions))
				ledger.CommitTxBatch(0, genesisTransactions, nil, nil)
			}
		}()

		if getGenesis() == nil {
			genesisLogger.Info("No genesis block chaincodes defined.")
		} else {

			chaincodes, chaincodesOK := genesis["chaincodes"].(map[interface{}]interface{})
			if !chaincodesOK {
				genesisLogger.Info("No genesis block chaincodes defined.")
				ledger.CommitTxBatch(0, genesisTransactions, nil, nil)
				return
			}

			genesisLogger.Debugf("Genesis chaincodes are %s", chaincodes)

			for i := range chaincodes {
				name := i.(string)
				genesisLogger.Debugf("Chaincode %s", name)

				chaincode := chaincodes[name]
				chaincodeMap, chaincodeMapOK := chaincode.(map[interface{}]interface{})
				if !chaincodeMapOK {
					genesisLogger.Errorf("Invalid chaincode defined in genesis configuration: %s", chaincode)
					makeGenesisError = fmt.Errorf("Invalid chaincode defined in genesis configuration: %s", chaincode)
					return
				}

				path, pathOK := chaincodeMap["path"].(string)
				if !pathOK {
					genesisLogger.Errorf("Invalid chaincode URL defined in genesis configuration: %s", chaincodeMap["path"])
					makeGenesisError = fmt.Errorf("Invalid chaincode URL defined in genesis configuration: %s", chaincodeMap["path"])
					return
				}

				chaincodeType, chaincodeTypeOK := chaincodeMap["type"].(string)
				if !chaincodeTypeOK {
					genesisLogger.Errorf("Invalid chaincode type defined in genesis configuration: %s", chaincodeMap["type"])
					makeGenesisError = fmt.Errorf("Invalid chaincode type defined in genesis configuration: %s", chaincodeMap["type"])
					return
				}

				if chaincodeType == "" {
					chaincodeType = "GOLANG"
				}

				chaincodeID := &protos.ChaincodeID{Path: path, Name: name}

				genesisLogger.Debugf("Genesis chaincodeID %s", chaincodeID)

				constructorMap, constructorMapOK := chaincodeMap["constructor"].(map[interface{}]interface{})
				if !constructorMapOK {
					genesisLogger.Errorf("Invalid chaincode constructor defined in genesis configuration: %s", chaincodeMap["constructor"])
					makeGenesisError = fmt.Errorf("Invalid chaincode constructor defined in genesis configuration: %s", chaincodeMap["constructor"])
					return
				}

				var spec protos.ChaincodeSpec
				if constructorMap == nil {
					genesisLogger.Debug("Genesis chaincode has no constructor.")
					spec = protos.ChaincodeSpec{Type: protos.ChaincodeSpec_Type(protos.ChaincodeSpec_Type_value[chaincodeType]), ChaincodeID: chaincodeID}
				} else {

					_, ctorArgsOK := constructorMap["args"]
					if !ctorArgsOK {
						genesisLogger.Errorf("Invalid chaincode constructor args defined in genesis configuration: %s", constructorMap["args"])
						makeGenesisError = fmt.Errorf("Invalid chaincode constructor args defined in genesis configuration: %s", constructorMap["args"])
						return
					}

					ctorArgs, ctorArgsOK := constructorMap["args"].([]interface{})
					var ctorArgsStringArray []string
					if ctorArgsOK {
						genesisLogger.Debugf("Genesis chaincode constructor args %s", ctorArgs)
						for j := 0; j < len(ctorArgs); j++ {
							ctorArgsStringArray = append(ctorArgsStringArray, ctorArgs[j].(string))
						}
					}
					spec = protos.ChaincodeSpec{Type: protos.ChaincodeSpec_Type(protos.ChaincodeSpec_Type_value[chaincodeType]), ChaincodeID: chaincodeID, CtorMsg: &protos.ChaincodeInput{Args: ctorArgsStringArray}}
				}

				transaction, _, deployErr := DeployLocal(context.Background(), &spec, genesisBlockExists)
				if deployErr != nil {
					genesisLogger.Errorf("Error deploying chaincode for genesis block: %s", deployErr)
					makeGenesisError = deployErr
					return
				}

				genesisTransactions = append(genesisTransactions, transaction)

			} //for

		} //else
	})
	return makeGenesisError
}

//BuildLocal builds a given chaincode code
func BuildLocal(context context.Context, spec *protos.ChaincodeSpec) (*protos.ChaincodeDeploymentSpec, error) {
	genesisLogger.Debugf("Received build request for chaincode spec: %v", spec)
	var codePackageBytes []byte
	/*****  We will need this only when we support non-go SYSTEM chaincode ****
	if getMode() != chaincode.DevModeUserRunsChaincode {
		if err := core.CheckSpec(spec); err != nil {
			genesisLogger.Debugf("check spec failed: %s", err)
			return nil, err
		}
		// Build the spec
		var err error
		codePackageBytes, err = container.GetChaincodePackageBytes(spec)
		if err != nil {
			genesisLogger.Errorf("Error getting VM: %s", err)
			return nil, err
		}
	}
	*********/
	chaincodeDeploymentSpec := &protos.ChaincodeDeploymentSpec{ExecEnv: protos.ChaincodeDeploymentSpec_SYSTEM, ChaincodeSpec: spec, CodePackage: codePackageBytes}
	return chaincodeDeploymentSpec, nil
}

// DeployLocal deploys the supplied chaincode image to the local peer
func DeployLocal(ctx context.Context, spec *protos.ChaincodeSpec, gbexists bool) (*protos.Transaction, []byte, error) {
	// First build and get the deployment spec
	chaincodeDeploymentSpec, err := BuildLocal(ctx, spec)

	if err != nil {
		genesisLogger.Errorf("Error deploying chaincode spec: %v\n\n error: %s", spec, err)
		return nil, nil, err
	}

	var transaction *protos.Transaction
	if gbexists {
		ledger, err := ledger.GetLedger()
		if err != nil {
			return nil, nil, fmt.Errorf("Failed to get handle to ledger (%s)", err)
		}
		transaction, err = ledger.GetTransactionByUUID(chaincodeDeploymentSpec.ChaincodeSpec.ChaincodeID.Name)
		if err != nil {
			genesisLogger.Warningf("cannot get deployment transaction for %s - %s", chaincodeDeploymentSpec.ChaincodeSpec.ChaincodeID.Name, err)
			transaction = nil
		} else {
			genesisLogger.Debugf("deployment transaction for %s exists", chaincodeDeploymentSpec.ChaincodeSpec.ChaincodeID.Name)
		}
	}

	if transaction == nil {
		transaction, err = protos.NewChaincodeDeployTransaction(chaincodeDeploymentSpec, chaincodeDeploymentSpec.ChaincodeSpec.ChaincodeID.Name)
		if err != nil {
			return nil, nil, fmt.Errorf("Error deploying chaincode: %s ", err)
		}
	}

	//chaincode.NewChaincodeSupport(chaincode.DefaultChain, peer.GetPeerEndpoint, false, 120000)
	// The secHelper is set during creat ChaincodeSupport, so we don't need this step
	//ctx = context.WithValue(ctx, "security", secCxt)
	result, _, err := chaincode.Execute(ctx, chaincode.GetChain(chaincode.DefaultChain), transaction)
	return transaction, result, err
}

<|endoftext|>


<commit_before>package main

import (
	"image"
	cp "image/color/palette"
	"image/gif"
	"io"
	"log"
	"math"
	"math/rand"
	"net/http"
)

var palette = cp.WebSafe

const (
	blackIndex = 0
)

func main() {
	handler := func(w http.ResponseWriter, r *http.Request) {
		lissajous(w)
	}
	http.HandleFunc("/", handler)
	log.Fatal(http.ListenAndServe("localhost:8000", nil))
}

func lissajous(out io.Writer) {
	const (
		cycles  = 5
		res     = 0.001
		size    = 100
		nframes = 64
		delay   = 8
	)
	freq := rand.Float64() * 3.0
	anim := gif.GIF{LoopCount: nframes}
	phase := 0.0
	for i := 0; i < nframes; i++ {
		rect := image.Rect(0, 0, 2*size+1, 2*size+1)
		img := image.NewPaletted(rect, palette)
		color := rand.Intn(216)
		for t := 0.0; t < cycles*2*math.Pi; t += res {
			x := math.Sin(t)
			y := math.Sin(t*freq + phase)
			img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), uint8(color))
		}
		phase += 0.1
		anim.Delay = append(anim.Delay, delay)
		anim.Image = append(anim.Image, img)
	}
	gif.EncodeAll(out, &anim)
}
<commit_msg>lissajous server with parameterized cycles ex 1.12<commit_after>package main

import (
	"image"
	cp "image/color/palette"
	"image/gif"
	"io"
	"log"
	"math"
	"math/rand"
	"net/http"
	"strconv"
	"strings"
)

var palette = cp.WebSafe

const (
	blackIndex = 0
)

func main() {
	handler := func(w http.ResponseWriter, r *http.Request) {
		if err := r.ParseForm(); err != nil {
			log.Print(err)
		}
		cycles := 0
		for k, v := range r.Form {
			if k == "cycles" {
				cycles, _ = strconv.Atoi(strings.Join(v, ""))
			}
		}
		lissajous(w, cycles)
	}
	http.HandleFunc("/", handler)
	log.Fatal(http.ListenAndServe("localhost:8000", nil))
}

func lissajous(out io.Writer, cycles int) {
	if cycles == 0 {
		cycles = 5
	}
	const (
		res     = 0.001
		size    = 100
		nframes = 64
		delay   = 8
	)
	freq := rand.Float64() * 3.0
	anim := gif.GIF{LoopCount: nframes}
	phase := 0.0
	for i := 0; i < nframes; i++ {
		rect := image.Rect(0, 0, 2*size+1, 2*size+1)
		img := image.NewPaletted(rect, palette)
		color := rand.Intn(216)
		for t := 0.0; t < float64(cycles)*2*math.Pi; t += res {
			x := math.Sin(t)
			y := math.Sin(t*freq + phase)
			img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), uint8(color))
		}
		phase += 0.1
		anim.Delay = append(anim.Delay, delay)
		anim.Image = append(anim.Image, img)
	}
	gif.EncodeAll(out, &anim)
}
<|endoftext|>


<commit_before>// +build rpi

/*
  Go Language Raspberry Pi Interface
  (c) Copyright David Thorpe 2016-2017
  All Rights Reserved

  Documentation http://djthorpe.github.io/gopi/
  For Licensing and Usage information, please see LICENSE.md
*/

package rpi

import (
	"fmt"
)

////////////////////////////////////////////////////////////////////////////////
// TYPES

type Model uint
type Processor uint
type Revision uint

type Product struct {
	model       Model
	processor   Processor
	revision    Revision
	warrantyBit bool
}

////////////////////////////////////////////////////////////////////////////////
// CONSTANTS

const (
	RPI_WARRANTY_MASK     uint32 = 0x03000000
	RPI_ENCODING_MASK     uint32 = 0x00800000
	RPI_REVISION_MASK     uint32 = 0x0000000F
	RPI_MODEL_MASK        uint32 = 0x00000FF0
	RPI_PROCESSOR_MASK    uint32 = 0x0000F000
	RPI_MANUFACTURER_MASK uint32 = 0x000F0000
	RPI_MEMORY_MASK       uint32 = 0x00700000
)

const (
	RPI_MODEL_A                Model = (0 << 4)
	RPI_MODEL_B                Model = (1 << 4)
	RPI_MODEL_A_PLUS           Model = (2 << 4)
	RPI_MODEL_B_PLUS           Model = (3 << 4)
	RPI_MODEL_B_PI_2           Model = (4 << 4)
	RPI_MODEL_ALPHA            Model = (5 << 4)
	RPI_MODEL_COMPUTE_MODULE   Model = (6 << 4)
	RPI_MODEL_ZERO             Model = (7 << 4)
	RPI_MODEL_B_PI_3           Model = (8 << 4)
	RPI_MODEL_COMPUTE_MODULE_3 Model = (9 << 4)
	RPI_MODEL_ZERO_W           Model = (10 << 4)
	RPI_MODEL_UNKNOWN          Model = (15 << 4)
)

const (
	RPI_PROCESSOR_UNKNOWN Processor = 0xFFFFFFFF
	RPI_PROCESSOR_BCM2835 Processor = (0 << 12)
	RPI_PROCESSOR_BCM2836 Processor = (1 << 12)
	RPI_PROCESSOR_BCM2837 Processor = (2 << 12)
)

const (
	RPI_REVISION_UNKNOWN Revision = 0
)

////////////////////////////////////////////////////////////////////////////////
// GLOBAL VARIABLES

var (
	productmap1 = map[uint32]Model{
		0x02: RPI_MODEL_B,
		0x03: RPI_MODEL_B,
		0x04: RPI_MODEL_B,
		0x05: RPI_MODEL_B,
		0x06: RPI_MODEL_B,
		0x07: RPI_MODEL_A,
		0x08: RPI_MODEL_A,
		0x09: RPI_MODEL_A,
		0x0D: RPI_MODEL_B,
		0x0E: RPI_MODEL_B,
		0x0F: RPI_MODEL_B,
		0x10: RPI_MODEL_B_PLUS,
		0x11: RPI_MODEL_COMPUTE_MODULE,
		0x12: RPI_MODEL_A_PLUS,
		0x13: RPI_MODEL_B_PLUS,
		0x14: RPI_MODEL_COMPUTE_MODULE,
		0x15: RPI_MODEL_A_PLUS,
	}
	pcbmap1 = map[uint32]Revision{
		0x02: Revision(1),
		0x03: Revision(1),
		0x04: Revision(2),
		0x05: Revision(2),
		0x06: Revision(2),
		0x07: Revision(2),
		0x08: Revision(2),
		0x09: Revision(2),
		0x0D: Revision(2),
		0x0E: Revision(2),
		0x0F: Revision(2),
		0x10: Revision(1),
		0x11: Revision(1),
		0x12: Revision(1),
		0x13: Revision(1),
		0x14: Revision(1),
		0x15: Revision(1),
	}
)

////////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS

func (this *hardware) GetProduct() (*Product, error) {
	if r, err := this.GetRevisionUint32(); err != nil {
		return nil, err
	} else {
		model, revision := modelRevision(r)
		return &Product{model, processor(r), revision, warrantyBit(r)}, nil
	}
}

////////////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS

// warrantyBit returns the value of the warranty bit
func warrantyBit(revision uint32) bool {
	return ((revision & uint32(RPI_WARRANTY_MASK)) != 0)
}

// modelRevision returns model and revision information
func modelRevision(revision uint32) (Model, Revision) {
	revision = revision & ^RPI_WARRANTY_MASK
	if (revision & RPI_ENCODING_MASK) != 0 {
		// Raspberry Pi 2 style revision coding
		return Model(revision & RPI_MODEL_MASK), Revision(revision & RPI_REVISION_MASK)
	} else {
		// Raspberry Pi 1 style revision coding
		if model, ok := productmap1[revision]; !ok {
			return RPI_MODEL_UNKNOWN, RPI_REVISION_UNKNOWN
		} else if pcb, ok := pcbmap1[revision]; !ok {
			return RPI_MODEL_UNKNOWN, RPI_REVISION_UNKNOWN
		} else {
			return model, pcb
		}
	}
}

// processor returns processor information
func processor(revision uint32) Processor {
	revision = revision & ^RPI_WARRANTY_MASK
	if (revision & RPI_ENCODING_MASK) != 0 {
		// Raspberry Pi 2 style revision coding
		return Processor(revision & RPI_PROCESSOR_MASK)
	} else {
		// Raspberry Pi 1 style revision coding
		return RPI_PROCESSOR_BCM2835
	}
}

////////////////////////////////////////////////////////////////////////////////
// STRINGIFY

func (p *Product) String() string {
	return fmt.Sprintf("sys.hw.rpi.Product{ model=%v processor=%v revision=%v warrantyBit=%v }", p.model, p.processor, p.revision, p.warrantyBit)
}

func (m Model) String() string {
	switch m {
	case RPI_MODEL_A:
		return "RPI_MODEL_A"
	case RPI_MODEL_B:
		return "RPI_MODEL_B"
	case RPI_MODEL_A_PLUS:
		return "RPI_MODEL_A_PLUS"
	case RPI_MODEL_B_PLUS:
		return "RPI_MODEL_B_PLUS"
	case RPI_MODEL_B_PI_2:
		return "RPI_MODEL_B_PI_2"
	case RPI_MODEL_B_PI_3:
		return "RPI_MODEL_B_PI_3"
	case RPI_MODEL_ALPHA:
		return "RPI_MODEL_ALPHA"
	case RPI_MODEL_COMPUTE_MODULE:
		return "RPI_MODEL_COMPUTE_MODULE"
	case RPI_MODEL_COMPUTE_MODULE_3:
		return "RPI_MODEL_COMPUTE_MODULE_3"
	case RPI_MODEL_ZERO:
		return "RPI_MODEL_ZERO"
	case RPI_MODEL_ZERO_W:
		return "RPI_MODEL_ZERO_W"
	default:
		return fmt.Sprintf("[?? Unknown Model value %d]", uint32(m))
	}
}

func (p Processor) String() string {
	switch p {
	case RPI_PROCESSOR_BCM2835:
		return "RPI_PROCESSOR_BCM2835"
	case RPI_PROCESSOR_BCM2836:
		return "RPI_PROCESSOR_BCM2836"
	case RPI_PROCESSOR_BCM2837:
		return "RPI_PROCESSOR_BCM2837"
	default:
		return "[?? Unknown Processor value]"
	}
}

func (p Revision) String() string {
	if p == RPI_REVISION_UNKNOWN {
		return "[?? Unknwon Revision value]"
	}
	return fmt.Sprintf("RPI_REVISION_V%v", uint(p))
}
<commit_msg>Fixed model values<commit_after>// +build rpi

/*
  Go Language Raspberry Pi Interface
  (c) Copyright David Thorpe 2016-2017
  All Rights Reserved

  Documentation http://djthorpe.github.io/gopi/
  For Licensing and Usage information, please see LICENSE.md
*/

package rpi

import (
	"fmt"
)

////////////////////////////////////////////////////////////////////////////////
// TYPES

type Model uint
type Processor uint
type Revision uint

type Product struct {
	model       Model
	processor   Processor
	revision    Revision
	warrantyBit bool
}

////////////////////////////////////////////////////////////////////////////////
// CONSTANTS

const (
	RPI_WARRANTY_MASK     uint32 = 0x03000000
	RPI_ENCODING_MASK     uint32 = 0x00800000
	RPI_REVISION_MASK     uint32 = 0x0000000F
	RPI_MODEL_MASK        uint32 = 0x00000FF0
	RPI_PROCESSOR_MASK    uint32 = 0x0000F000
	RPI_MANUFACTURER_MASK uint32 = 0x000F0000
	RPI_MEMORY_MASK       uint32 = 0x00700000
)

const (
	RPI_MODEL_A                Model = (0x00 << 4)
	RPI_MODEL_B                Model = (0x01 << 4)
	RPI_MODEL_A_PLUS           Model = (0x02 << 4)
	RPI_MODEL_B_PLUS           Model = (0x03 << 4)
	RPI_MODEL_B_PI_2           Model = (0x04 << 4)
	RPI_MODEL_ALPHA            Model = (0x05 << 4)
	RPI_MODEL_COMPUTE_MODULE   Model = (0x06 << 4)
	RPI_MODEL_B_PI_3           Model = (0x08 << 4)
	RPI_MODEL_ZERO             Model = (0x09 << 4)
	RPI_MODEL_COMPUTE_MODULE_3 Model = (0x0A << 4)
	RPI_MODEL_ZERO_W           Model = (0x0C << 4)
	RPI_MODEL_UNKNOWN          Model = (0x0F << 4)
)

const (
	RPI_PROCESSOR_UNKNOWN Processor = 0xFFFFFFFF
	RPI_PROCESSOR_BCM2835 Processor = (0 << 12)
	RPI_PROCESSOR_BCM2836 Processor = (1 << 12)
	RPI_PROCESSOR_BCM2837 Processor = (2 << 12)
)

const (
	RPI_REVISION_UNKNOWN Revision = 0
)

////////////////////////////////////////////////////////////////////////////////
// GLOBAL VARIABLES

var (
	productmap1 = map[uint32]Model{
		0x02: RPI_MODEL_B,
		0x03: RPI_MODEL_B,
		0x04: RPI_MODEL_B,
		0x05: RPI_MODEL_B,
		0x06: RPI_MODEL_B,
		0x07: RPI_MODEL_A,
		0x08: RPI_MODEL_A,
		0x09: RPI_MODEL_A,
		0x0D: RPI_MODEL_B,
		0x0E: RPI_MODEL_B,
		0x0F: RPI_MODEL_B,
		0x10: RPI_MODEL_B_PLUS,
		0x11: RPI_MODEL_COMPUTE_MODULE,
		0x12: RPI_MODEL_A_PLUS,
		0x13: RPI_MODEL_B_PLUS,
		0x14: RPI_MODEL_COMPUTE_MODULE,
		0x15: RPI_MODEL_A_PLUS,
	}
	pcbmap1 = map[uint32]Revision{
		0x02: Revision(1),
		0x03: Revision(1),
		0x04: Revision(2),
		0x05: Revision(2),
		0x06: Revision(2),
		0x07: Revision(2),
		0x08: Revision(2),
		0x09: Revision(2),
		0x0D: Revision(2),
		0x0E: Revision(2),
		0x0F: Revision(2),
		0x10: Revision(1),
		0x11: Revision(1),
		0x12: Revision(1),
		0x13: Revision(1),
		0x14: Revision(1),
		0x15: Revision(1),
	}
)

////////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS

func (this *hardware) GetProduct() (*Product, error) {
	if r, err := this.GetRevisionUint32(); err != nil {
		return nil, err
	} else {
		model, revision := modelRevision(r)
		return &Product{model, processor(r), revision, warrantyBit(r)}, nil
	}
}

////////////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS

// warrantyBit returns the value of the warranty bit
func warrantyBit(revision uint32) bool {
	return ((revision & uint32(RPI_WARRANTY_MASK)) != 0)
}

// modelRevision returns model and revision information
func modelRevision(revision uint32) (Model, Revision) {
	revision = revision & ^RPI_WARRANTY_MASK
	if (revision & RPI_ENCODING_MASK) != 0 {
		// Raspberry Pi 2 style revision coding
		return Model(revision & RPI_MODEL_MASK), Revision(revision & RPI_REVISION_MASK)
	} else {
		// Raspberry Pi 1 style revision coding
		if model, ok := productmap1[revision]; !ok {
			return RPI_MODEL_UNKNOWN, RPI_REVISION_UNKNOWN
		} else if pcb, ok := pcbmap1[revision]; !ok {
			return RPI_MODEL_UNKNOWN, RPI_REVISION_UNKNOWN
		} else {
			return model, pcb
		}
	}
}

// processor returns processor information
func processor(revision uint32) Processor {
	revision = revision & ^RPI_WARRANTY_MASK
	if (revision & RPI_ENCODING_MASK) != 0 {
		// Raspberry Pi 2 style revision coding
		return Processor(revision & RPI_PROCESSOR_MASK)
	} else {
		// Raspberry Pi 1 style revision coding
		return RPI_PROCESSOR_BCM2835
	}
}

////////////////////////////////////////////////////////////////////////////////
// STRINGIFY

func (p *Product) String() string {
	return fmt.Sprintf("sys.hw.rpi.Product{ model=%v processor=%v revision=%v warrantyBit=%v }", p.model, p.processor, p.revision, p.warrantyBit)
}

func (m Model) String() string {
	switch m {
	case RPI_MODEL_A:
		return "RPI_MODEL_A"
	case RPI_MODEL_B:
		return "RPI_MODEL_B"
	case RPI_MODEL_A_PLUS:
		return "RPI_MODEL_A_PLUS"
	case RPI_MODEL_B_PLUS:
		return "RPI_MODEL_B_PLUS"
	case RPI_MODEL_B_PI_2:
		return "RPI_MODEL_B_PI_2"
	case RPI_MODEL_B_PI_3:
		return "RPI_MODEL_B_PI_3"
	case RPI_MODEL_ALPHA:
		return "RPI_MODEL_ALPHA"
	case RPI_MODEL_COMPUTE_MODULE:
		return "RPI_MODEL_COMPUTE_MODULE"
	case RPI_MODEL_COMPUTE_MODULE_3:
		return "RPI_MODEL_COMPUTE_MODULE_3"
	case RPI_MODEL_ZERO:
		return "RPI_MODEL_ZERO"
	case RPI_MODEL_ZERO_W:
		return "RPI_MODEL_ZERO_W"
	default:
		return fmt.Sprintf("[?? Unknown Model value 0x%02X]", uint32(m))
	}
}

func (p Processor) String() string {
	switch p {
	case RPI_PROCESSOR_BCM2835:
		return "RPI_PROCESSOR_BCM2835"
	case RPI_PROCESSOR_BCM2836:
		return "RPI_PROCESSOR_BCM2836"
	case RPI_PROCESSOR_BCM2837:
		return "RPI_PROCESSOR_BCM2837"
	default:
		return "[?? Unknown Processor value]"
	}
}

func (p Revision) String() string {
	if p == RPI_REVISION_UNKNOWN {
		return "[?? Unknwon Revision value]"
	}
	return fmt.Sprintf("RPI_REVISION_V%v", uint(p))
}
<|endoftext|>


<commit_before>package singularity

import (
	"github.com/opentable/sous/ext/docker"
	"github.com/opentable/sous/lib"
)

// DummyNameCache implements the Builder interface by returning a
// computed image name for a given source version
type DummyRegistry struct {
}

// NewDummyNameCache builds a new DummyNameCache
func NewDummyRegistry() *DummyRegistry {
	return &DummyRegistry{}
}

// TODO: Factor out name cache concept from core sous lib & get rid of this func.
func (dc *DummyRegistry) GetArtifact(sv sous.SourceVersion) (*sous.BuildArtifact, error) {
	return docker.DockerBuildArtifact(sv.String()), nil
}

// GetSourceVersion implements part of ImageMapper
func (dc *DummyRegistry) GetSourceVersion(*sous.BuildArtifact) (sous.SourceVersion, error) {
	return sous.SourceVersion{}, nil
}
<commit_msg>Remove unnecessary docker ref in DummyRegistry<commit_after>package singularity

import "github.com/opentable/sous/lib"

// DummyNameCache implements the Builder interface by returning a
// computed image name for a given source version
type DummyRegistry struct {
}

// NewDummyNameCache builds a new DummyNameCache
func NewDummyRegistry() *DummyRegistry {
	return &DummyRegistry{}
}

// TODO: Factor out name cache concept from core sous lib & get rid of this func.
func (dc *DummyRegistry) GetArtifact(sv sous.SourceVersion) (*sous.BuildArtifact, error) {
	return &sous.BuildArtifact{Name: sv.String(), Type: "dummy"}, nil
}

// GetSourceVersion implements part of ImageMapper
func (dc *DummyRegistry) GetSourceVersion(*sous.BuildArtifact) (sous.SourceVersion, error) {
	return sous.SourceVersion{}, nil
}
<|endoftext|>


<commit_before>//Package memory provides a lightweight in memory store for onecache
//Do take a look at other stores
package memory

import (
	"github.com/adelowo/onecache"
	"sync"
	"time"
)

//Represents an inmemory store
type InMemoryStore struct {
	sync.RWMutex
	data map[string][]byte
}

//Returns a new instance of the Inmemory store
func NewInMemoryStore() *InMemoryStore {
	return &InMemoryStore{data: make(map[string][]byte)}
}

func (i *InMemoryStore) Set(key string, data interface{}, expires time.Duration) error {
	i.RLock()

	defer i.RUnlock()

	item := &onecache.Item{ExpiresAt: time.Now().Add(expires), Data: data}

	b, err := item.Bytes()

	if err != nil {
		return err
	}

	i.data[key] = b

	return nil
}

func (i *InMemoryStore) Get(key string) (interface{}, error) {
	i.RLock()
	defer i.RUnlock()

	bytes, ok := i.data[key]

	if !ok {
		return nil, onecache.ErrCacheMiss
	}

	item, err := onecache.BytesToItem(bytes)

	if err != nil {
		return nil, err
	}

	return item.Data, nil
}

func (i *InMemoryStore) Delete(key string) error {
	i.RLock()
	defer i.RUnlock()

	_, ok := i.data[key]

	if !ok {
		return onecache.ErrCacheMiss
	}

	delete(i.data, key)

	return nil
}
<commit_msg>Garbage collect expired items<commit_after>//Package memory provides a lightweight in memory store for onecache
//Do take a look at other stores
package memory

import (
	"github.com/adelowo/onecache"
	"sync"
	"time"
)

//Represents an inmemory store
type InMemoryStore struct {
	sync.RWMutex
	data map[string][]byte
}

//Returns a new instance of the Inmemory store
func NewInMemoryStore() *InMemoryStore {
	return &InMemoryStore{data: make(map[string][]byte)}
}

func (i *InMemoryStore) Set(key string, data interface{}, expires time.Duration) error {
	i.RLock()

	defer i.RUnlock()

	item := &onecache.Item{ExpiresAt: time.Now().Add(expires), Data: data}

	b, err := item.Bytes()

	if err != nil {
		return err
	}

	i.data[key] = b

	return nil
}

func (i *InMemoryStore) Get(key string) (interface{}, error) {
	i.RLock()
	defer i.RUnlock()

	bytes, ok := i.data[key]

	if !ok {
		return nil, onecache.ErrCacheMiss
	}

	item, err := onecache.BytesToItem(bytes)

	if item.IsExpired() {
		i.Delete(key)
		return nil, onecache.ErrCacheMiss
	}

	if err != nil {
		return nil, err
	}

	return item.Data, nil
}

func (i *InMemoryStore) Delete(key string) error {
	i.RLock()
	defer i.RUnlock()

	_, ok := i.data[key]

	if !ok {
		return onecache.ErrCacheMiss
	}

	delete(i.data, key)

	return nil
}
<|endoftext|>


<commit_before>package models

import (
	"bytes"
	"math"
	"sort"
	"strconv"
	"strings"

	"github.com/grafana/metrictank/consolidation"
	"github.com/grafana/metrictank/expr/tagquery"
	"github.com/grafana/metrictank/schema"
	pickle "github.com/kisielk/og-rek"
)

//go:generate msgp

type Series struct {
	Target       string            // for fetched data, set from models.Req.Target, i.e. the metric graphite key. for function output, whatever should be shown as target string (legend)
	Tags         map[string]string // Must be set initially via call to `SetTags()`
	Interval     uint32
	QueryPatt    string                     // to tie series back to request it came from. e.g. foo.bar.*, or if series outputted by func it would be e.g. scale(foo.bar.*,0.123456)
	QueryFrom    uint32                     // to tie series back to request it came from
	QueryTo      uint32                     // to tie series back to request it came from
	QueryCons    consolidation.Consolidator // to tie series back to request it came from (may be 0 to mean use configured default)
	Consolidator consolidation.Consolidator // consolidator to actually use (for fetched series this may not be 0, default must be resolved. if series created by function, may be 0)
	Meta         SeriesMeta                 // note: this series could be a "just fetched" series, or one derived from many other series
	Datapoints   []schema.Point
}

// SeriesMeta counts the number of series for each set of meta properties
// note: it's illegal for SeriesMeta to include multiple entries that include the same properties
type SeriesMeta []SeriesMetaProperties

// SeriesMetaProperties describes the properties of a series
// (fetching and normalization and the count of series corresponding to them)
type SeriesMetaProperties struct {
	SchemaID              uint16                     // id of storage-schemas rule this series corresponds to
	Archive               uint8                      // which archive was being read from
	AggNumNorm            uint32                     // aggNum for normalization
	AggNumRC              uint32                     // aggNum runtime consolidation
	ConsolidatorNormFetch consolidation.Consolidator // consolidator used for normalization and reading from store (if applicable)
	ConsolidatorRC        consolidation.Consolidator // consolidator used for runtime consolidation to honor maxdatapoints (if applicable).
	Count                 uint32                     // number of series corresponding to these properties
}

// Merge merges SeriesMeta b into a
// counts for identical properties get added together
func (a SeriesMeta) Merge(b SeriesMeta) SeriesMeta {
	// note: to see which properties are equivalent we should not consider the count
	indices := make(map[SeriesMetaProperties]int)
	for i, v := range a {
		v.Count = 0
		indices[v] = i
	}
	for j, v := range b {
		v.Count = 0
		index, ok := indices[v]
		if ok {
			a[index].Count += b[j].Count
		} else {
			a = append(a, b[j])
		}
	}
	return a
}

// Copy creates a copy of SeriesMeta
func (a SeriesMeta) Copy() SeriesMeta {
	out := make(SeriesMeta, len(a))
	copy(out, a)
	return out
}

// CopyWithChange creates a copy of SeriesMeta, but executes the requested change on each each SeriesMetaProperties
func (a SeriesMeta) CopyWithChange(fn func(in SeriesMetaProperties) SeriesMetaProperties) SeriesMeta {
	out := make(SeriesMeta, len(a))
	for i, v := range a {
		out[i] = fn(v)
	}
	return out
}

func (s *Series) SetTags() {
	numTags := strings.Count(s.Target, ";")

	if s.Tags == nil {
		// +1 for the name tag
		s.Tags = make(map[string]string, numTags+1)
	} else {
		for k := range s.Tags {
			delete(s.Tags, k)
		}
	}

	if numTags == 0 {
		s.Tags["name"] = s.Target
		return
	}

	index := strings.IndexByte(s.Target, ';')
	name := s.Target[:index]

	remainder := s.Target
	for index > 0 {
		remainder = remainder[index+1:]
		index = strings.IndexByte(remainder, ';')

		tagPair := remainder
		if index > 0 {
			tagPair = remainder[:index]
		}

		equalsPos := strings.IndexByte(tagPair, '=')
		if equalsPos < 1 {
			// Shouldn't happen
			continue
		}

		s.Tags[tagPair[:equalsPos]] = tagPair[equalsPos+1:]
	}

	// Do this last to overwrite any "name" tag that might have been specified in the series tags.
	s.Tags["name"] = name
}

func (s *Series) EnrichWithTags(tags tagquery.Tags) {
	// every serie has at least one tag, the name tag
	// if there are no tags defined, this means the tags must not have been set yet
	if len(s.Tags) == 0 {
		s.SetTags()
	}

	for _, tag := range tags {
		if _, ok := s.Tags[tag.Key]; !ok {
			s.Tags[tag.Key] = tag.Value
		}
	}

	s.buildTargetFromTags()
}

func (s *Series) buildTargetFromTags() {
	buf := bytes.NewBufferString(s.Tags["name"])

	keys := make([]string, 0, len(s.Tags)-1)
	for key := range s.Tags {
		if key == "name" {
			continue
		}
		keys = append(keys, key)
	}

	sort.Strings(keys)

	for _, key := range keys {
		buf.WriteRune(';')
		buf.WriteString(key)
		buf.WriteRune('=')
		buf.WriteString(s.Tags[key])
	}

	s.Target = buf.String()
}

// Copy returns a deep copy.
// The returned value does not link to the same memory space for any of the properties
func (s Series) Copy(emptyDatapoints []schema.Point) Series {
	return Series{
		Target:       s.Target,
		Datapoints:   append(emptyDatapoints, s.Datapoints...),
		Tags:         s.CopyTags(),
		Interval:     s.Interval,
		QueryPatt:    s.QueryPatt,
		QueryFrom:    s.QueryFrom,
		QueryTo:      s.QueryTo,
		QueryCons:    s.QueryCons,
		Consolidator: s.Consolidator,
		Meta:         s.Meta.Copy(),
	}
}

// CopyTags makes a deep copy of the tags
func (s *Series) CopyTags() map[string]string {
	out := make(map[string]string, len(s.Tags))
	for k, v := range s.Tags {
		out[k] = v
	}
	return out
}

// CopyTagsWith makes a deep copy of the tags and sets the given tag
func (s *Series) CopyTagsWith(key, val string) map[string]string {
	out := make(map[string]string, len(s.Tags)+1)
	for k, v := range s.Tags {
		out[k] = v
	}
	out[key] = val
	return out
}

type SeriesByTarget []Series

func (g SeriesByTarget) Len() int           { return len(g) }
func (g SeriesByTarget) Swap(i, j int)      { g[i], g[j] = g[j], g[i] }
func (g SeriesByTarget) Less(i, j int) bool { return g[i].Target < g[j].Target }

// regular graphite output
func (series SeriesByTarget) MarshalJSONFast(b []byte) ([]byte, error) {
	b = append(b, '[')
	for _, s := range series {
		b = append(b, `{"target":`...)
		b = strconv.AppendQuoteToASCII(b, s.Target)
		if len(s.Tags) != 0 {
			b = append(b, `,"tags":{`...)
			for name, value := range s.Tags {
				b = strconv.AppendQuoteToASCII(b, name)
				b = append(b, ':')
				b = strconv.AppendQuoteToASCII(b, value)
				b = append(b, ',')
			}
			// Replace trailing comma with a closing bracket
			b[len(b)-1] = '}'
		}
		b = append(b, `,"datapoints":[`...)
		for _, p := range s.Datapoints {
			b = append(b, '[')
			if math.IsNaN(p.Val) {
				b = append(b, `null,`...)
			} else {
				b = strconv.AppendFloat(b, p.Val, 'f', -1, 64)
				b = append(b, ',')
			}
			b = strconv.AppendUint(b, uint64(p.Ts), 10)
			b = append(b, `],`...)
		}
		if len(s.Datapoints) != 0 {
			b = b[:len(b)-1] // cut last comma
		}
		b = append(b, `]},`...)
	}
	if len(series) != 0 {
		b = b[:len(b)-1] // cut last comma
	}
	b = append(b, ']')
	return b, nil
}
func (series SeriesByTarget) MarshalJSONFastWithMeta(b []byte) ([]byte, error) {
	b = append(b, '[')
	for _, s := range series {
		b = append(b, `{"target":`...)
		b = strconv.AppendQuoteToASCII(b, s.Target)
		if len(s.Tags) != 0 {
			b = append(b, `,"tags":{`...)
			for name, value := range s.Tags {
				b = strconv.AppendQuoteToASCII(b, name)
				b = append(b, ':')
				b = strconv.AppendQuoteToASCII(b, value)
				b = append(b, ',')
			}
			// Replace trailing comma with a closing bracket
			b[len(b)-1] = '}'
		}
		b = append(b, `,"datapoints":[`...)
		for _, p := range s.Datapoints {
			b = append(b, '[')
			if math.IsNaN(p.Val) {
				b = append(b, `null,`...)
			} else {
				b = strconv.AppendFloat(b, p.Val, 'f', -1, 64)
				b = append(b, ',')
			}
			b = strconv.AppendUint(b, uint64(p.Ts), 10)
			b = append(b, `],`...)
		}
		if len(s.Datapoints) != 0 {
			b = b[:len(b)-1] // cut last comma
		}
		b = append(b, `],"meta":`...)
		b, _ = s.Meta.MarshalJSONFast(b)
		b = append(b, `},`...)
	}
	if len(series) != 0 {
		b = b[:len(b)-1] // cut last comma
	}
	b = append(b, ']')
	return b, nil
}

func (meta SeriesMeta) MarshalJSONFast(b []byte) ([]byte, error) {
	b = append(b, '[')
	for _, props := range meta {
		b = append(b, `{"schema-id":`...)
		// TODO make user friendly return the actual rule
		b = strconv.AppendUint(b, uint64(props.SchemaID), 10)
		b = append(b, `,"archive":`...)
		b = strconv.AppendUint(b, uint64(props.Archive), 10)
		b = append(b, `,"aggnum-norm":`...)
		b = strconv.AppendUint(b, uint64(props.AggNumNorm), 10)
		b = append(b, `,"consolidate-normfetch":"`...)
		b = append(b, props.ConsolidatorNormFetch.String()...)
		b = append(b, `","aggnum-rc":`...)
		b = strconv.AppendUint(b, uint64(props.AggNumRC), 10)
		b = append(b, `,"consolidate-rc":"`...)
		b = append(b, props.ConsolidatorRC.String()...)
		b = append(b, `","count":`...)
		b = strconv.AppendUint(b, uint64(props.Count), 10)
		b = append(b, `},`...)
	}
	if len(meta) != 0 {
		b = b[:len(b)-1] // cut last comma
	}
	b = append(b, ']')
	return b, nil

}

func (series SeriesByTarget) MarshalJSON() ([]byte, error) {
	return series.MarshalJSONFast(nil)
}

func (series SeriesByTarget) ForGraphite(format string) SeriesListForPickle {
	var none interface{}
	if format == "pickle" {
		none = pickle.None{}
	}
	data := make(SeriesListForPickle, len(series))
	for i, s := range series {
		datapoints := make([]interface{}, len(s.Datapoints))
		for j, p := range s.Datapoints {
			if math.IsNaN(p.Val) {
				datapoints[j] = none
			} else {
				datapoints[j] = p.Val
			}
		}
		data[i] = SeriesForPickle{
			Name:           s.Target,
			Step:           s.Interval,
			Values:         datapoints,
			PathExpression: s.QueryPatt,
		}
		if len(datapoints) > 0 {
			data[i].Start = s.Datapoints[0].Ts
			data[i].End = s.Datapoints[len(s.Datapoints)-1].Ts + s.Interval
		} else {
			data[i].Start = s.QueryFrom
			data[i].End = s.QueryTo
		}
	}
	return data
}

func (series SeriesByTarget) Pickle(buf []byte) ([]byte, error) {
	buffer := bytes.NewBuffer(buf)
	encoder := pickle.NewEncoder(buffer)
	err := encoder.Encode(series.ForGraphite("pickle"))
	return buffer.Bytes(), err
}

type SeriesListForPickle []SeriesForPickle

type SeriesForPickle struct {
	Name           string        `pickle:"name" msg:"name"`
	Start          uint32        `pickle:"start" msg:"start"`
	End            uint32        `pickle:"end" msg:"end"`
	Step           uint32        `pickle:"step" msg:"step"`
	Values         []interface{} `pickle:"values" msg:"values"`
	PathExpression string        `pickle:"pathExpression" msg:"pathExpression"`
}
<commit_msg>Update api/models/series.go<commit_after>package models

import (
	"bytes"
	"math"
	"sort"
	"strconv"
	"strings"

	"github.com/grafana/metrictank/consolidation"
	"github.com/grafana/metrictank/expr/tagquery"
	"github.com/grafana/metrictank/schema"
	pickle "github.com/kisielk/og-rek"
)

//go:generate msgp

type Series struct {
	Target       string            // for fetched data, set from models.Req.Target, i.e. the metric graphite key. for function output, whatever should be shown as target string (legend)
	Tags         map[string]string // Must be set initially via call to `SetTags()`
	Interval     uint32
	QueryPatt    string                     // to tie series back to request it came from. e.g. foo.bar.*, or if series outputted by func it would be e.g. scale(foo.bar.*,0.123456)
	QueryFrom    uint32                     // to tie series back to request it came from
	QueryTo      uint32                     // to tie series back to request it came from
	QueryCons    consolidation.Consolidator // to tie series back to request it came from (may be 0 to mean use configured default)
	Consolidator consolidation.Consolidator // consolidator to actually use (for fetched series this may not be 0, default must be resolved. if series created by function, may be 0)
	Meta         SeriesMeta                 // note: this series could be a "just fetched" series, or one derived from many other series
	Datapoints   []schema.Point
}

// SeriesMeta counts the number of series for each set of meta properties
// note: it's illegal for SeriesMeta to include multiple entries that include the same properties
type SeriesMeta []SeriesMetaProperties

// SeriesMetaProperties describes the properties of a series
// (fetching and normalization and the count of series corresponding to them)
type SeriesMetaProperties struct {
	SchemaID              uint16                     // id of storage-schemas rule this series corresponds to
	Archive               uint8                      // which archive was being read from
	AggNumNorm            uint32                     // aggNum for normalization
	AggNumRC              uint32                     // aggNum runtime consolidation
	ConsolidatorNormFetch consolidation.Consolidator // consolidator used for normalization and reading from store (if applicable)
	ConsolidatorRC        consolidation.Consolidator // consolidator used for runtime consolidation to honor maxdatapoints (if applicable).
	Count                 uint32                     // number of series corresponding to these properties
}

// Merge merges SeriesMeta b into a
// counts for identical properties get added together
func (a SeriesMeta) Merge(b SeriesMeta) SeriesMeta {
	// note: to see which properties are equivalent we should not consider the count
	indices := make(map[SeriesMetaProperties]int)
	for i, v := range a {
		v.Count = 0
		indices[v] = i
	}
	for j, v := range b {
		v.Count = 0
		index, ok := indices[v]
		if ok {
			a[index].Count += b[j].Count
		} else {
			a = append(a, b[j])
		}
	}
	return a
}

// Copy creates a copy of SeriesMeta
func (a SeriesMeta) Copy() SeriesMeta {
	out := make(SeriesMeta, len(a))
	copy(out, a)
	return out
}

// CopyWithChange creates a copy of SeriesMeta, but executes the requested change on each SeriesMetaProperties
func (a SeriesMeta) CopyWithChange(fn func(in SeriesMetaProperties) SeriesMetaProperties) SeriesMeta {
	out := make(SeriesMeta, len(a))
	for i, v := range a {
		out[i] = fn(v)
	}
	return out
}

func (s *Series) SetTags() {
	numTags := strings.Count(s.Target, ";")

	if s.Tags == nil {
		// +1 for the name tag
		s.Tags = make(map[string]string, numTags+1)
	} else {
		for k := range s.Tags {
			delete(s.Tags, k)
		}
	}

	if numTags == 0 {
		s.Tags["name"] = s.Target
		return
	}

	index := strings.IndexByte(s.Target, ';')
	name := s.Target[:index]

	remainder := s.Target
	for index > 0 {
		remainder = remainder[index+1:]
		index = strings.IndexByte(remainder, ';')

		tagPair := remainder
		if index > 0 {
			tagPair = remainder[:index]
		}

		equalsPos := strings.IndexByte(tagPair, '=')
		if equalsPos < 1 {
			// Shouldn't happen
			continue
		}

		s.Tags[tagPair[:equalsPos]] = tagPair[equalsPos+1:]
	}

	// Do this last to overwrite any "name" tag that might have been specified in the series tags.
	s.Tags["name"] = name
}

func (s *Series) EnrichWithTags(tags tagquery.Tags) {
	// every serie has at least one tag, the name tag
	// if there are no tags defined, this means the tags must not have been set yet
	if len(s.Tags) == 0 {
		s.SetTags()
	}

	for _, tag := range tags {
		if _, ok := s.Tags[tag.Key]; !ok {
			s.Tags[tag.Key] = tag.Value
		}
	}

	s.buildTargetFromTags()
}

func (s *Series) buildTargetFromTags() {
	buf := bytes.NewBufferString(s.Tags["name"])

	keys := make([]string, 0, len(s.Tags)-1)
	for key := range s.Tags {
		if key == "name" {
			continue
		}
		keys = append(keys, key)
	}

	sort.Strings(keys)

	for _, key := range keys {
		buf.WriteRune(';')
		buf.WriteString(key)
		buf.WriteRune('=')
		buf.WriteString(s.Tags[key])
	}

	s.Target = buf.String()
}

// Copy returns a deep copy.
// The returned value does not link to the same memory space for any of the properties
func (s Series) Copy(emptyDatapoints []schema.Point) Series {
	return Series{
		Target:       s.Target,
		Datapoints:   append(emptyDatapoints, s.Datapoints...),
		Tags:         s.CopyTags(),
		Interval:     s.Interval,
		QueryPatt:    s.QueryPatt,
		QueryFrom:    s.QueryFrom,
		QueryTo:      s.QueryTo,
		QueryCons:    s.QueryCons,
		Consolidator: s.Consolidator,
		Meta:         s.Meta.Copy(),
	}
}

// CopyTags makes a deep copy of the tags
func (s *Series) CopyTags() map[string]string {
	out := make(map[string]string, len(s.Tags))
	for k, v := range s.Tags {
		out[k] = v
	}
	return out
}

// CopyTagsWith makes a deep copy of the tags and sets the given tag
func (s *Series) CopyTagsWith(key, val string) map[string]string {
	out := make(map[string]string, len(s.Tags)+1)
	for k, v := range s.Tags {
		out[k] = v
	}
	out[key] = val
	return out
}

type SeriesByTarget []Series

func (g SeriesByTarget) Len() int           { return len(g) }
func (g SeriesByTarget) Swap(i, j int)      { g[i], g[j] = g[j], g[i] }
func (g SeriesByTarget) Less(i, j int) bool { return g[i].Target < g[j].Target }

// regular graphite output
func (series SeriesByTarget) MarshalJSONFast(b []byte) ([]byte, error) {
	b = append(b, '[')
	for _, s := range series {
		b = append(b, `{"target":`...)
		b = strconv.AppendQuoteToASCII(b, s.Target)
		if len(s.Tags) != 0 {
			b = append(b, `,"tags":{`...)
			for name, value := range s.Tags {
				b = strconv.AppendQuoteToASCII(b, name)
				b = append(b, ':')
				b = strconv.AppendQuoteToASCII(b, value)
				b = append(b, ',')
			}
			// Replace trailing comma with a closing bracket
			b[len(b)-1] = '}'
		}
		b = append(b, `,"datapoints":[`...)
		for _, p := range s.Datapoints {
			b = append(b, '[')
			if math.IsNaN(p.Val) {
				b = append(b, `null,`...)
			} else {
				b = strconv.AppendFloat(b, p.Val, 'f', -1, 64)
				b = append(b, ',')
			}
			b = strconv.AppendUint(b, uint64(p.Ts), 10)
			b = append(b, `],`...)
		}
		if len(s.Datapoints) != 0 {
			b = b[:len(b)-1] // cut last comma
		}
		b = append(b, `]},`...)
	}
	if len(series) != 0 {
		b = b[:len(b)-1] // cut last comma
	}
	b = append(b, ']')
	return b, nil
}
func (series SeriesByTarget) MarshalJSONFastWithMeta(b []byte) ([]byte, error) {
	b = append(b, '[')
	for _, s := range series {
		b = append(b, `{"target":`...)
		b = strconv.AppendQuoteToASCII(b, s.Target)
		if len(s.Tags) != 0 {
			b = append(b, `,"tags":{`...)
			for name, value := range s.Tags {
				b = strconv.AppendQuoteToASCII(b, name)
				b = append(b, ':')
				b = strconv.AppendQuoteToASCII(b, value)
				b = append(b, ',')
			}
			// Replace trailing comma with a closing bracket
			b[len(b)-1] = '}'
		}
		b = append(b, `,"datapoints":[`...)
		for _, p := range s.Datapoints {
			b = append(b, '[')
			if math.IsNaN(p.Val) {
				b = append(b, `null,`...)
			} else {
				b = strconv.AppendFloat(b, p.Val, 'f', -1, 64)
				b = append(b, ',')
			}
			b = strconv.AppendUint(b, uint64(p.Ts), 10)
			b = append(b, `],`...)
		}
		if len(s.Datapoints) != 0 {
			b = b[:len(b)-1] // cut last comma
		}
		b = append(b, `],"meta":`...)
		b, _ = s.Meta.MarshalJSONFast(b)
		b = append(b, `},`...)
	}
	if len(series) != 0 {
		b = b[:len(b)-1] // cut last comma
	}
	b = append(b, ']')
	return b, nil
}

func (meta SeriesMeta) MarshalJSONFast(b []byte) ([]byte, error) {
	b = append(b, '[')
	for _, props := range meta {
		b = append(b, `{"schema-id":`...)
		// TODO make user friendly return the actual rule
		b = strconv.AppendUint(b, uint64(props.SchemaID), 10)
		b = append(b, `,"archive":`...)
		b = strconv.AppendUint(b, uint64(props.Archive), 10)
		b = append(b, `,"aggnum-norm":`...)
		b = strconv.AppendUint(b, uint64(props.AggNumNorm), 10)
		b = append(b, `,"consolidate-normfetch":"`...)
		b = append(b, props.ConsolidatorNormFetch.String()...)
		b = append(b, `","aggnum-rc":`...)
		b = strconv.AppendUint(b, uint64(props.AggNumRC), 10)
		b = append(b, `,"consolidate-rc":"`...)
		b = append(b, props.ConsolidatorRC.String()...)
		b = append(b, `","count":`...)
		b = strconv.AppendUint(b, uint64(props.Count), 10)
		b = append(b, `},`...)
	}
	if len(meta) != 0 {
		b = b[:len(b)-1] // cut last comma
	}
	b = append(b, ']')
	return b, nil

}

func (series SeriesByTarget) MarshalJSON() ([]byte, error) {
	return series.MarshalJSONFast(nil)
}

func (series SeriesByTarget) ForGraphite(format string) SeriesListForPickle {
	var none interface{}
	if format == "pickle" {
		none = pickle.None{}
	}
	data := make(SeriesListForPickle, len(series))
	for i, s := range series {
		datapoints := make([]interface{}, len(s.Datapoints))
		for j, p := range s.Datapoints {
			if math.IsNaN(p.Val) {
				datapoints[j] = none
			} else {
				datapoints[j] = p.Val
			}
		}
		data[i] = SeriesForPickle{
			Name:           s.Target,
			Step:           s.Interval,
			Values:         datapoints,
			PathExpression: s.QueryPatt,
		}
		if len(datapoints) > 0 {
			data[i].Start = s.Datapoints[0].Ts
			data[i].End = s.Datapoints[len(s.Datapoints)-1].Ts + s.Interval
		} else {
			data[i].Start = s.QueryFrom
			data[i].End = s.QueryTo
		}
	}
	return data
}

func (series SeriesByTarget) Pickle(buf []byte) ([]byte, error) {
	buffer := bytes.NewBuffer(buf)
	encoder := pickle.NewEncoder(buffer)
	err := encoder.Encode(series.ForGraphite("pickle"))
	return buffer.Bytes(), err
}

type SeriesListForPickle []SeriesForPickle

type SeriesForPickle struct {
	Name           string        `pickle:"name" msg:"name"`
	Start          uint32        `pickle:"start" msg:"start"`
	End            uint32        `pickle:"end" msg:"end"`
	Step           uint32        `pickle:"step" msg:"step"`
	Values         []interface{} `pickle:"values" msg:"values"`
	PathExpression string        `pickle:"pathExpression" msg:"pathExpression"`
}
<|endoftext|>


<commit_before>// Copyright 2022 Google LLC
//
// 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
//
//     https://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 ezcx

import (
	"bytes"
	"context"
	"io"
	"net/http"

	"github.com/google/uuid"
	cx "google.golang.org/genproto/googleapis/cloud/dialogflow/cx/v3"
	"google.golang.org/protobuf/encoding/protojson"
	"google.golang.org/protobuf/types/known/structpb"
)

type WebhookRequest struct {
	cx.WebhookRequest
	// 2022-10-08: Replaced context.Context with func () context.Context.
	ctx func() context.Context
}

func NewWebhookRequest() *WebhookRequest {
	return new(WebhookRequest)
}

// WebhookRequest Initializations

// Initialize the PageInfo field
func (req *WebhookRequest) initPageInfo() {
	if req.PageInfo == nil {
		req.PageInfo = new(cx.PageInfo)
	}
	if req.PageInfo.FormInfo == nil {
		req.PageInfo.FormInfo = new(cx.PageInfo_FormInfo)
	}
	if req.PageInfo.FormInfo.ParameterInfo == nil {
		req.PageInfo.FormInfo.ParameterInfo = make([]*cx.PageInfo_FormInfo_ParameterInfo, 0)
	}
}

// Initialize the SessionInfo field
func (req *WebhookRequest) initSessionInfo() {
	if req.SessionInfo == nil {
		req.SessionInfo = new(cx.SessionInfo)
	}
}

// Initialize the Payload field
func (req *WebhookRequest) initPayload() {
	if req.Payload == nil {
		req.Payload = new(structpb.Struct)
	}
	if req.Payload.Fields == nil {
		req.Payload.Fields = make(map[string]*structpb.Value)
	}
}

func (req *WebhookRequest) Context() context.Context {
	return req.ctx()
}

// Sets (overrides) the PageInfo.ParameterInfos to match the provided map m
func (req *WebhookRequest) setPageFormParameters(m map[string]any) error {
	params := make([]*cx.PageInfo_FormInfo_ParameterInfo, 0)
	for k, v := range m {
		var formParameter cx.PageInfo_FormInfo_ParameterInfo
		pv, err := anyToProto(v)
		if err != nil {
			return err
		}
		formParameter.DisplayName = k
		formParameter.Value = pv
		formParameter.State = cx.PageInfo_FormInfo_ParameterInfo_FILLED
		params = append(params, &formParameter)
	}
	req.PageInfo.FormInfo.ParameterInfo = params
	return nil
}

// Sets (overrides) the SessionInfo.Parameters to match the provided map m
func (req *WebhookRequest) setSessionParameters(m map[string]any) error {
	pm, err := anyToProtoMap(m)
	if err != nil {
		return err
	}
	req.SessionInfo.Parameters = pm
	return nil
}

// Sets (overrides the SessionInfo.Parameters) to match the provided map m
func (req *WebhookRequest) setPayload(m map[string]any) error {
	pm, err := anyToProtoMap(m)
	if err != nil {
		return err
	}
	req.Payload.Fields = pm
	return nil
}

// yaquino@2022-10-11: Dialogflow CX API May include "extra" fields that may
// throw errors and interface with protojson.Unmarshal.  As per the documentation,
// these fields may be ignored.
func WebhookRequestFromReader(rd io.Reader) (*WebhookRequest, error) {
	var req WebhookRequest
	b, err := io.ReadAll(rd)
	if err != nil {
		return nil, err
	}
	unmarshaler := &protojson.UnmarshalOptions{
		DiscardUnknown: true,
	}
	err = unmarshaler.Unmarshal(b, &req.WebhookRequest)
	if err != nil {
		return nil, err
	}
	return &req, nil
}

// yaquino@2022-10-07: Refactored to flow http.Request's context to the
// WebhookRequest instance.
func WebhookRequestFromRequest(r *http.Request) (*WebhookRequest, error) {
	req, err := WebhookRequestFromReader(r.Body)
	if err != nil {
		return nil, err
	}
	return req, nil
}

func (req *WebhookRequest) ReadReader(rd io.Reader) error {
	b, err := io.ReadAll(rd)
	if err != nil {
		return err
	}
	unmarshaler := &protojson.UnmarshalOptions{
		DiscardUnknown: true,
	}
	err = unmarshaler.Unmarshal(b, &req.WebhookRequest)
	if err != nil {
		return err
	}
	return nil
}

func (req *WebhookRequest) ReadRequest(r *http.Request) error {
	return req.ReadReader(r.Body)
}

// Is this the right format??
func (req *WebhookRequest) WriteRequest(w io.Writer) error {
	m := protojson.MarshalOptions{Indent: "\t"}
	b, err := m.Marshal(&req.WebhookRequest)
	if err != nil {
		return err
	}
	r := bytes.NewReader(b)
	_, err = io.Copy(w, r)
	if err != nil {
		return err
	}
	return nil
}

func (req *WebhookRequest) InitializeResponse() *WebhookResponse {
	return req.initializeResponse()
}

func (req *WebhookRequest) initializeResponse() *WebhookResponse {
	resp := NewWebhookResponse()
	return req.copySession(resp)
}

func (req *WebhookRequest) copySession(res *WebhookResponse) *WebhookResponse {
	if res.SessionInfo == nil {
		res.SessionInfo = new(cx.SessionInfo)
	}
	res.SessionInfo.Session = req.SessionInfo.Session
	return res
}

func (req *WebhookRequest) CopyPageInfo(res *WebhookResponse) {
	if req.PageInfo != nil {
		res.PageInfo = req.PageInfo
	}
}

func (req *WebhookRequest) CopySessionInfo(res *WebhookResponse) *WebhookResponse {
	if req.SessionInfo != nil {
		res.SessionInfo = req.SessionInfo
	}
	return res
}

func (req *WebhookRequest) CopyPayload(res *WebhookResponse) *WebhookResponse {
	if req.Payload != nil {
		res.Payload = req.Payload
	}
	return res
}

func (req *WebhookRequest) GetPageFormParameters() map[string]any {
	params := make(map[string]any)

	// Just in case - I don't think we can iterate over a nil map.
	if req.PageInfo == nil {
		return nil
	}
	if req.PageInfo.FormInfo == nil {
		return nil
	}
	if req.PageInfo.FormInfo.ParameterInfo == nil {
		return nil
	}

	for _, paramInfo := range req.PageInfo.FormInfo.ParameterInfo {
		params[paramInfo.DisplayName] = protoToAny(paramInfo.Value)
	}

	return params
}

func (req *WebhookRequest) GetSessionParameters() map[string]any {
	if req.SessionInfo == nil {
		return nil
	}
	if req.SessionInfo.Parameters == nil {
		return nil
	}
	return protoToAnyMap(req.SessionInfo.Parameters)
}

func (req *WebhookRequest) GetSessionParameter(key string) (any, bool) {
	// Check if SessionInfo Parameters is nil.
	if req.SessionInfo == nil {
		return nil, false
	}
	if req.SessionInfo.Parameters == nil {
		return nil, false
	}
	pv, ok := req.SessionInfo.Parameters[key]
	return protoToAny(pv), ok
}

func (req *WebhookRequest) GetPayload() map[string]any {
	if req.Payload == nil {
		return nil
	}
	if req.Payload.Fields == nil {
		return nil
	}
	return protoToAnyMap(req.Payload.Fields)
}

func (req *WebhookRequest) GetPayloadParameter(key string) (any, bool) {
	// Just in case - I don't think we can iterate over a nil map.

	if req.Payload == nil {
		return nil, false
	}
	if req.Payload.Fields == nil {
		return nil, false
	}

	pv, ok := req.Payload.Fields[key]
	return protoToAny(pv), ok
}

// Testing
func NewTestingWebhookRequest(session, payload, pageform map[string]any) (*WebhookRequest, error) {
	return NewWebhookRequest().initTestingWebhookRequest(session, payload, pageform)
}

func (req *WebhookRequest) initTestingWebhookRequest(session, payload, pageform map[string]any) (*WebhookRequest, error) {
	// Provided for testing, normally http.Request.Context is flowed down.
	req.ctx = context.Background

	// All incoming WebhookRequests should have a session.
	req.initSessionInfo()
	req.SessionInfo.Session = uuid.New().String()

	// if session parameters are provided...
	if session != nil {
		err := req.setSessionParameters(session)
		if err != nil {
			return nil, err
		}
	}

	// if payload parameters are provided...
	if payload != nil {
		req.initPayload()
		err := req.setPayload(payload)
		if err != nil {
			return nil, err
		}
	}

	// if pageForm parameters are provided...
	if pageform != nil {
		req.initPageInfo()
		err := req.setPageFormParameters(pageform)
		if err != nil {
			return nil, err
		}
	}
	return req, nil
}

// yaquino: 2022-10-08Review this...!
func (req *WebhookRequest) TestCxHandler(out io.Writer, h HandlerFunc) (*WebhookResponse, error) {
	if req.ctx == nil {
		req.ctx = context.Background
	}
	res := req.initializeResponse()
	err := h(res, req)
	if err != nil {
		return nil, err
	}
	err = res.WriteResponse(out)
	if err != nil {
		return nil, err
	}
	return res, nil
}
<commit_msg>new proto unmarshaler<commit_after>// Copyright 2022 Google LLC
//
// 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
//
//     https://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 ezcx

import (
	"bytes"
	"context"
	"io"
	"net/http"

	"github.com/google/uuid"
	cx "google.golang.org/genproto/googleapis/cloud/dialogflow/cx/v3"
	"google.golang.org/protobuf/encoding/protojson"
	"google.golang.org/protobuf/types/known/structpb"
)

type WebhookRequest struct {
	cx.WebhookRequest
	// 2022-10-08: Replaced context.Context with func () context.Context.
	ctx func() context.Context
}

func NewWebhookRequest() *WebhookRequest {
	return new(WebhookRequest)
}

// WebhookRequest Initializations

// Initialize the PageInfo field
func (req *WebhookRequest) initPageInfo() {
	if req.PageInfo == nil {
		req.PageInfo = new(cx.PageInfo)
	}
	if req.PageInfo.FormInfo == nil {
		req.PageInfo.FormInfo = new(cx.PageInfo_FormInfo)
	}
	if req.PageInfo.FormInfo.ParameterInfo == nil {
		req.PageInfo.FormInfo.ParameterInfo = make([]*cx.PageInfo_FormInfo_ParameterInfo, 0)
	}
}

// Initialize the SessionInfo field
func (req *WebhookRequest) initSessionInfo() {
	if req.SessionInfo == nil {
		req.SessionInfo = new(cx.SessionInfo)
	}
}

// Initialize the Payload field
func (req *WebhookRequest) initPayload() {
	if req.Payload == nil {
		req.Payload = new(structpb.Struct)
	}
	if req.Payload.Fields == nil {
		req.Payload.Fields = make(map[string]*structpb.Value)
	}
}

func (req *WebhookRequest) Context() context.Context {
	return req.ctx()
}

// Sets (overrides) the PageInfo.ParameterInfos to match the provided map m
func (req *WebhookRequest) setPageFormParameters(m map[string]any) error {
	params := make([]*cx.PageInfo_FormInfo_ParameterInfo, 0)
	for k, v := range m {
		var formParameter cx.PageInfo_FormInfo_ParameterInfo
		pv, err := anyToProto(v)
		if err != nil {
			return err
		}
		formParameter.DisplayName = k
		formParameter.Value = pv
		formParameter.State = cx.PageInfo_FormInfo_ParameterInfo_FILLED
		params = append(params, &formParameter)
	}
	req.PageInfo.FormInfo.ParameterInfo = params
	return nil
}

// Sets (overrides) the SessionInfo.Parameters to match the provided map m
func (req *WebhookRequest) setSessionParameters(m map[string]any) error {
	pm, err := anyToProtoMap(m)
	if err != nil {
		return err
	}
	req.SessionInfo.Parameters = pm
	return nil
}

// Sets (overrides the SessionInfo.Parameters) to match the provided map m
func (req *WebhookRequest) setPayload(m map[string]any) error {
	pm, err := anyToProtoMap(m)
	if err != nil {
		return err
	}
	req.Payload.Fields = pm
	return nil
}

// yaquino@2022-10-11: Dialogflow CX API May include "extra" fields that may
// throw errors and interface with protojson.Unmarshal.  As per the documentation,
// these fields may be ignored. Now also pointing at req.WebhookRequest for unmarshalling.
func WebhookRequestFromReader(rd io.Reader) (*WebhookRequest, error) {
	var req WebhookRequest
	b, err := io.ReadAll(rd)
	if err != nil {
		return nil, err
	}
	unmarshaler := &protojson.UnmarshalOptions{
		DiscardUnknown: true,
	}
	err = unmarshaler.Unmarshal(b, &req.WebhookRequest)
	if err != nil {
		return nil, err
	}
	return &req, nil
}

// yaquino@2022-10-07: Refactored to flow http.Request's context to the
// WebhookRequest instance.
func WebhookRequestFromRequest(r *http.Request) (*WebhookRequest, error) {
	req, err := WebhookRequestFromReader(r.Body)
	if err != nil {
		return nil, err
	}
	return req, nil
}

func (req *WebhookRequest) ReadReader(rd io.Reader) error {
	b, err := io.ReadAll(rd)
	if err != nil {
		return err
	}
	unmarshaler := &protojson.UnmarshalOptions{
		DiscardUnknown: true,
	}
	err = unmarshaler.Unmarshal(b, &req.WebhookRequest)
	if err != nil {
		return err
	}
	return nil
}

func (req *WebhookRequest) ReadRequest(r *http.Request) error {
	return req.ReadReader(r.Body)
}

// Is this the right format??
func (req *WebhookRequest) WriteRequest(w io.Writer) error {
	m := protojson.MarshalOptions{Indent: "\t"}
	b, err := m.Marshal(&req.WebhookRequest)
	if err != nil {
		return err
	}
	r := bytes.NewReader(b)
	_, err = io.Copy(w, r)
	if err != nil {
		return err
	}
	return nil
}

func (req *WebhookRequest) InitializeResponse() *WebhookResponse {
	return req.initializeResponse()
}

func (req *WebhookRequest) initializeResponse() *WebhookResponse {
	resp := NewWebhookResponse()
	return req.copySession(resp)
}

func (req *WebhookRequest) copySession(res *WebhookResponse) *WebhookResponse {
	if res.SessionInfo == nil {
		res.SessionInfo = new(cx.SessionInfo)
	}
	res.SessionInfo.Session = req.SessionInfo.Session
	return res
}

func (req *WebhookRequest) CopyPageInfo(res *WebhookResponse) {
	if req.PageInfo != nil {
		res.PageInfo = req.PageInfo
	}
}

func (req *WebhookRequest) CopySessionInfo(res *WebhookResponse) *WebhookResponse {
	if req.SessionInfo != nil {
		res.SessionInfo = req.SessionInfo
	}
	return res
}

func (req *WebhookRequest) CopyPayload(res *WebhookResponse) *WebhookResponse {
	if req.Payload != nil {
		res.Payload = req.Payload
	}
	return res
}

func (req *WebhookRequest) GetPageFormParameters() map[string]any {
	params := make(map[string]any)

	// Just in case - I don't think we can iterate over a nil map.
	if req.PageInfo == nil {
		return nil
	}
	if req.PageInfo.FormInfo == nil {
		return nil
	}
	if req.PageInfo.FormInfo.ParameterInfo == nil {
		return nil
	}

	for _, paramInfo := range req.PageInfo.FormInfo.ParameterInfo {
		params[paramInfo.DisplayName] = protoToAny(paramInfo.Value)
	}

	return params
}

func (req *WebhookRequest) GetSessionParameters() map[string]any {
	if req.SessionInfo == nil {
		return nil
	}
	if req.SessionInfo.Parameters == nil {
		return nil
	}
	return protoToAnyMap(req.SessionInfo.Parameters)
}

func (req *WebhookRequest) GetSessionParameter(key string) (any, bool) {
	// Check if SessionInfo Parameters is nil.
	if req.SessionInfo == nil {
		return nil, false
	}
	if req.SessionInfo.Parameters == nil {
		return nil, false
	}
	pv, ok := req.SessionInfo.Parameters[key]
	return protoToAny(pv), ok
}

func (req *WebhookRequest) GetPayload() map[string]any {
	if req.Payload == nil {
		return nil
	}
	if req.Payload.Fields == nil {
		return nil
	}
	return protoToAnyMap(req.Payload.Fields)
}

func (req *WebhookRequest) GetPayloadParameter(key string) (any, bool) {
	// Just in case - I don't think we can iterate over a nil map.

	if req.Payload == nil {
		return nil, false
	}
	if req.Payload.Fields == nil {
		return nil, false
	}

	pv, ok := req.Payload.Fields[key]
	return protoToAny(pv), ok
}

// Testing
func NewTestingWebhookRequest(session, payload, pageform map[string]any) (*WebhookRequest, error) {
	return NewWebhookRequest().initTestingWebhookRequest(session, payload, pageform)
}

func (req *WebhookRequest) initTestingWebhookRequest(session, payload, pageform map[string]any) (*WebhookRequest, error) {
	// Provided for testing, normally http.Request.Context is flowed down.
	req.ctx = context.Background

	// All incoming WebhookRequests should have a session.
	req.initSessionInfo()
	req.SessionInfo.Session = uuid.New().String()

	// if session parameters are provided...
	if session != nil {
		err := req.setSessionParameters(session)
		if err != nil {
			return nil, err
		}
	}

	// if payload parameters are provided...
	if payload != nil {
		req.initPayload()
		err := req.setPayload(payload)
		if err != nil {
			return nil, err
		}
	}

	// if pageForm parameters are provided...
	if pageform != nil {
		req.initPageInfo()
		err := req.setPageFormParameters(pageform)
		if err != nil {
			return nil, err
		}
	}
	return req, nil
}

// yaquino: 2022-10-08Review this...!
func (req *WebhookRequest) TestCxHandler(out io.Writer, h HandlerFunc) (*WebhookResponse, error) {
	if req.ctx == nil {
		req.ctx = context.Background
	}
	res := req.initializeResponse()
	err := h(res, req)
	if err != nil {
		return nil, err
	}
	err = res.WriteResponse(out)
	if err != nil {
		return nil, err
	}
	return res, nil
}
<|endoftext|>


<commit_before>package config

import (
	"testing"
	"time"

	"github.com/fern4lvarez/piladb/config/vars"
)

func TestMaxStackSize(t *testing.T) {
	c := NewConfig()

	inputOutput := []struct {
		input  interface{}
		output int
	}{
		{8, 8},
		{-1, -1},
		{23.7, 23},
		{"3", 3},
		{"foo", -1},
		{[]byte("foo"), -1},
	}

	for _, io := range inputOutput {
		c.Set(vars.MaxStackSize, io.input)

		if s := c.MaxStackSize(); s != io.output {
			t.Errorf("MaxStackSize is %d, expected %d", s, io.output)
		}
	}
}

func TestReadTimeout(t *testing.T) {
	c := NewConfig()

	inputOutput := []struct {
		input  interface{}
		output time.Duration
	}{
		{8, 8},
		{-1, 30},
		{23.7, 23},
		{"3", 3},
		{"foo", 30},
		{[]byte("foo"), 30},
	}

	for _, io := range inputOutput {
		c.Set(vars.ReadTimeout, io.input)

		if s := c.ReadTimeout(); s != io.output {
			t.Errorf("ReadTimeout is %d, expected %d", s, io.output)
		}
	}
}

func TestWriteTimeout(t *testing.T) {
	c := NewConfig()

	inputOutput := []struct {
		input  interface{}
		output time.Duration
	}{
		{8, 8},
		{-1, 45},
		{23.7, 23},
		{"3", 3},
		{"foo", 45},
		{[]byte("foo"), 45},
	}

	for _, io := range inputOutput {
		c.Set(vars.WriteTimeout, io.input)

		if s := c.WriteTimeout(); s != io.output {
			t.Errorf("WriteTimeout is %d, expected %d", s, io.output)
		}
	}
}

func TestPort(t *testing.T) {
	c := NewConfig()

	inputOutput := []struct {
		input  interface{}
		output int
	}{
		{8090, 8090},
		{-1, 1205},
		{23676.7, 23676},
		{"3756", 3756},
		{"foo", 1205},
		{[]byte("foo"), 1205},
		{6736373635, 1205},
	}

	for _, io := range inputOutput {
		c.Set(vars.Port, io.input)

		if s := c.Port(); s != io.output {
			t.Errorf("Port is %d, expected %d", s, io.output)
		}
	}
}
<commit_msg>config: refine up tests<commit_after>package config

import (
	"testing"
	"time"

	"github.com/fern4lvarez/piladb/config/vars"
)

func TestMaxStackSize(t *testing.T) {
	c := NewConfig()

	inputOutput := []struct {
		input  interface{}
		output int
	}{
		{8, 8},
		{23.7, 23},
		{"3", 3},
		{-1, vars.MaxStackSizeDefault},
		{"foo", vars.MaxStackSizeDefault},
		{-35, vars.MaxStackSizeDefault},
		{[]byte("foo"), vars.MaxStackSizeDefault},
	}

	for _, io := range inputOutput {
		c.Set(vars.MaxStackSize, io.input)

		if s := c.MaxStackSize(); s != io.output {
			t.Errorf("MaxStackSize is %d, expected %d", s, io.output)
		}
	}
}

func TestReadTimeout(t *testing.T) {
	c := NewConfig()

	inputOutput := []struct {
		input  interface{}
		output time.Duration
	}{
		{8, 8},
		{23.7, 23},
		{"3", 3},
		{-1, vars.ReadTimeoutDefault},
		{"foo", vars.ReadTimeoutDefault},
		{[]byte("foo"), vars.ReadTimeoutDefault},
	}

	for _, io := range inputOutput {
		c.Set(vars.ReadTimeout, io.input)

		if s := c.ReadTimeout(); s != io.output {
			t.Errorf("ReadTimeout is %d, expected %d", s, io.output)
		}
	}
}

func TestWriteTimeout(t *testing.T) {
	c := NewConfig()

	inputOutput := []struct {
		input  interface{}
		output time.Duration
	}{
		{8, 8},
		{23.7, 23},
		{"3", 3},
		{-1, vars.WriteTimeoutDefault},
		{"foo", vars.WriteTimeoutDefault},
		{[]byte("foo"), vars.WriteTimeoutDefault},
	}

	for _, io := range inputOutput {
		c.Set(vars.WriteTimeout, io.input)

		if s := c.WriteTimeout(); s != io.output {
			t.Errorf("WriteTimeout is %d, expected %d", s, io.output)
		}
	}
}

func TestPort(t *testing.T) {
	c := NewConfig()

	inputOutput := []struct {
		input  interface{}
		output int
	}{
		{8090, 8090},
		{23676.7, 23676},
		{"3756", 3756},
		{-1, vars.PortDefault},
		{"foo", vars.PortDefault},
		{[]byte("foo"), vars.PortDefault},
		{6736373635, vars.PortDefault},
	}

	for _, io := range inputOutput {
		c.Set(vars.Port, io.input)

		if s := c.Port(); s != io.output {
			t.Errorf("Port is %d, expected %d", s, io.output)
		}
	}
}
<|endoftext|>


<commit_before>// Copyright © 2017 ben dewan <benj.dewan@gmail.com>
//
// 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.

package connection

import (
	compose "github.com/benjdewan/gocomposeapi"
)

const (
	actionUpdate            = "Updating"
	actionCreate            = "Creating"
	actionLookup            = "Looking up"
	actionDeprovision       = "Deprovisioning"
	actionDryRunUpdate      = "Pretending to update"
	actionDryRunCreate      = "Pretending to create"
	actionDryRunLookup      = "Pretending to lookup"
	actionDryRunDeprovision = "Pretending to deprovision"
)

type runFunc func(*Connection, Accessor) error

type cxnRunner struct {
	accessor Accessor
	run      runFunc
}

func (cxn *Connection) newRunners(accessors []Accessor) []cxnRunner {
	if cxn.dryRun {
		return cxn.newDryRunners(accessors)
	}
	runners := []cxnRunner{}
	for _, accessor := range accessors {
		runners = append(runners, cxnRunner{
			accessor: accessor,
			run:      cxn.assignRunFunc(accessor),
		})
	}
	return runners
}

func (cxn *Connection) newDryRunners(accessors []Accessor) []cxnRunner {
	runners := []cxnRunner{}
	for _, accessor := range accessors {
		runners = append(runners, cxnRunner{
			accessor: accessor,
			run:      cxn.assignDryRunFunc(accessor),
		})
	}
	return runners
}

func (cxn *Connection) assignRunFunc(accessor Accessor) runFunc {
	if !accessor.IsOwner() {
		cxn.pb.AddBar(actionLookup, accessor.GetName())
		return lookup
	} else if accessor.IsDeleter() {
		cxn.pb.AddBar(actionDeprovision, accessor.GetName())
		return deprovision
	}
	deployment, _ := cxn.client.GetDeploymentByName(accessor.GetName())
	return cxn.assignOwnerRunFunc(accessor.GetName(), deployment)

}

func (cxn *Connection) assignOwnerRunFunc(name string, deployment *compose.Deployment) runFunc {
	if deployment == nil {
		cxn.pb.AddBar(actionCreate, name)
		return create
	}
	cxn.pb.AddBar(actionUpdate, deployment.Name)
	// Cache this deployment struct for later reference
	cxn.deploymentsByName.Store(deployment.Name, deployment)
	return update
}

func (cxn *Connection) assignDryRunFunc(accessor Accessor) runFunc {
	if !accessor.IsOwner() {
		cxn.pb.AddBar(actionDryRunLookup, accessor.GetName())
		return dryRunLookup
	} else if accessor.IsDeleter() {
		cxn.pb.AddBar(actionDryRunDeprovision, accessor.GetName())
		return dryRunDeprovision
	}
	deployment, _ := cxn.client.GetDeploymentByName(accessor.GetName())
	return cxn.assignOwnerDryRunFunc(accessor.GetName(), deployment)
}

func (cxn *Connection) assignOwnerDryRunFunc(name string, deployment *compose.Deployment) runFunc {
	if deployment == nil {
		cxn.pb.AddBar(actionDryRunCreate, name)
		return dryRunCreate
	}

	cxn.pb.AddBar(actionDryRunUpdate, deployment.Name)
	// Cache this deployment struct for later reference
	cxn.deploymentsByName.Store(deployment.Name, deployment)
	return dryRunUpdate
}
<commit_msg>Build the cxnRunner slice in parallel<commit_after>// Copyright © 2017 ben dewan <benj.dewan@gmail.com>
//
// 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.

package connection

import (
	"sync"

	compose "github.com/benjdewan/gocomposeapi"
)

const (
	actionUpdate            = "Updating"
	actionCreate            = "Creating"
	actionLookup            = "Looking up"
	actionDeprovision       = "Deprovisioning"
	actionDryRunUpdate      = "Pretending to update"
	actionDryRunCreate      = "Pretending to create"
	actionDryRunLookup      = "Pretending to lookup"
	actionDryRunDeprovision = "Pretending to deprovision"
)

type runFunc func(*Connection, Accessor) error

type cxnRunner struct {
	accessor Accessor
	run      runFunc
}

func (cxn *Connection) newRunners(accessors []Accessor) []cxnRunner {
	if cxn.dryRun {
		return cxn.newDryRunners(accessors)
	}
	var wg sync.WaitGroup
	wg.Add(len(accessors))
	runners := make([]cxnRunner, len(accessors))

	for index, accessor := range accessors {
		go func(i int, a Accessor) {
			runners[i] = cxnRunner{
				accessor: a,
				run:      cxn.assignRunFunc(a),
			}
			wg.Done()
		}(index, accessor)
	}
	wg.Wait()
	return runners
}

func (cxn *Connection) newDryRunners(accessors []Accessor) []cxnRunner {
	var wg sync.WaitGroup
	wg.Add(len(accessors))
	runners := make([]cxnRunner, len(accessors))
	for index, accessor := range accessors {
		go func(i int, a Accessor) {
			runners[i] = cxnRunner{
				accessor: a,
				run:      cxn.assignDryRunFunc(a),
			}
			wg.Done()
		}(index, accessor)
	}
	wg.Wait()
	return runners
}

func (cxn *Connection) assignRunFunc(accessor Accessor) runFunc {
	if !accessor.IsOwner() {
		cxn.pb.AddBar(actionLookup, accessor.GetName())
		return lookup
	} else if accessor.IsDeleter() {
		cxn.pb.AddBar(actionDeprovision, accessor.GetName())
		return deprovision
	}
	deployment, _ := cxn.client.GetDeploymentByName(accessor.GetName())
	return cxn.assignOwnerRunFunc(accessor.GetName(), deployment)

}

func (cxn *Connection) assignOwnerRunFunc(name string, deployment *compose.Deployment) runFunc {
	if deployment == nil {
		cxn.pb.AddBar(actionCreate, name)
		return create
	}
	cxn.pb.AddBar(actionUpdate, deployment.Name)
	// Cache this deployment struct for later reference
	cxn.deploymentsByName.Store(deployment.Name, deployment)
	return update
}

func (cxn *Connection) assignDryRunFunc(accessor Accessor) runFunc {
	if !accessor.IsOwner() {
		cxn.pb.AddBar(actionDryRunLookup, accessor.GetName())
		return dryRunLookup
	} else if accessor.IsDeleter() {
		cxn.pb.AddBar(actionDryRunDeprovision, accessor.GetName())
		return dryRunDeprovision
	}
	deployment, _ := cxn.client.GetDeploymentByName(accessor.GetName())
	return cxn.assignOwnerDryRunFunc(accessor.GetName(), deployment)
}

func (cxn *Connection) assignOwnerDryRunFunc(name string, deployment *compose.Deployment) runFunc {
	if deployment == nil {
		cxn.pb.AddBar(actionDryRunCreate, name)
		return dryRunCreate
	}

	cxn.pb.AddBar(actionDryRunUpdate, deployment.Name)
	// Cache this deployment struct for later reference
	cxn.deploymentsByName.Store(deployment.Name, deployment)
	return dryRunUpdate
}
<|endoftext|>


<commit_before>package consensus

import (
	"strings"

	"github.com/bytom/protocol/bc"
)

//consensus variables
const (
	// Max gas that one block contains
	MaxBlockGas      = uint64(10000000)
	VMGasRate        = int64(200)
	StorageGasRate   = int64(1)
	MaxGasAmount     = int64(200000)
	DefaultGasCredit = int64(30000)

	//config parameter for coinbase reward
	CoinbasePendingBlockNumber = uint64(100)
	subsidyReductionInterval   = uint64(840000)
	baseSubsidy                = uint64(41250000000)
	InitialBlockSubsidy        = uint64(147000041250000000)

	// config for pow mining
	BlocksPerRetarget     = uint64(2016)
	TargetSecondsPerBlock = uint64(150)
	SeedPerRetarget       = uint64(256)

	// MaxTimeOffsetSeconds is the maximum number of seconds a block time is allowed to be ahead of the current time
	MaxTimeOffsetSeconds = uint64(60 * 60)
	MedianTimeBlocks     = 11

	PayToWitnessPubKeyHashDataSize = 20
	PayToWitnessScriptHashDataSize = 32
	CoinbaseArbitrarySizeLimit     = 128

	BTMAlias = "BTM"
)

// BTMAssetID is BTM's asset id, the soul asset of Bytom
var BTMAssetID = &bc.AssetID{
	V0: uint64(18446744073709551615),
	V1: uint64(18446744073709551615),
	V2: uint64(18446744073709551615),
	V3: uint64(18446744073709551615),
}

// InitialSeed is SHA3-256 of Byte[0^32]
var InitialSeed = &bc.Hash{
	V0: uint64(11412844483649490393),
	V1: uint64(4614157290180302959),
	V2: uint64(1780246333311066183),
	V3: uint64(9357197556716379726),
}

// BTMDefinitionMap is the ....
var BTMDefinitionMap = map[string]interface{}{
	"name":        BTMAlias,
	"symbol":      BTMAlias,
	"decimals":    8,
	"description": `Bytom Official Issue`,
}

// BlockSubsidy calculate the coinbase rewards on given block height
func BlockSubsidy(height uint64) uint64 {
	if height == 0 {
		return InitialBlockSubsidy
	}
	return baseSubsidy >> uint(height/subsidyReductionInterval)
}

// IsBech32SegwitPrefix returns whether the prefix is a known prefix for segwit
// addresses on any default or registered network.  This is used when decoding
// an address string into a specific address type.
func IsBech32SegwitPrefix(prefix string, params *Params) bool {
	prefix = strings.ToLower(prefix)
	return prefix == params.Bech32HRPSegwit+"1"
}

// Params store the config for different network
type Params struct {
	// Name defines a human-readable identifier for the network.
	Name            string
	Bech32HRPSegwit string
}

// ActiveNetParams is ...
var ActiveNetParams = MainNetParams

// NetParams is the correspondence between chain_id and Params
var NetParams = map[string]Params{
	"mainnet": MainNetParams,
	"testnet": TestNetParams,
	"solonet": SoloNetParams,

}

// MainNetParams is the config for production
var MainNetParams = Params{
	Name:            "main",
	Bech32HRPSegwit: "bm",
}

// TestNetParams is the config for test-net
var TestNetParams = Params{
	Name:            "test",
	Bech32HRPSegwit: "tm",
}

// TestNetParams is the config for test-net
var SoloNetParams = Params{
	Name:            "solo",
	Bech32HRPSegwit: "sm",
}
<commit_msg>change the genesis output value<commit_after>package consensus

import (
	"strings"

	"github.com/bytom/protocol/bc"
)

//consensus variables
const (
	// Max gas that one block contains
	MaxBlockGas      = uint64(10000000)
	VMGasRate        = int64(200)
	StorageGasRate   = int64(1)
	MaxGasAmount     = int64(200000)
	DefaultGasCredit = int64(30000)

	//config parameter for coinbase reward
	CoinbasePendingBlockNumber = uint64(100)
	subsidyReductionInterval   = uint64(840000)
	baseSubsidy                = uint64(41250000000)
	InitialBlockSubsidy        = uint64(140700041250000000)

	// config for pow mining
	BlocksPerRetarget     = uint64(2016)
	TargetSecondsPerBlock = uint64(150)
	SeedPerRetarget       = uint64(256)

	// MaxTimeOffsetSeconds is the maximum number of seconds a block time is allowed to be ahead of the current time
	MaxTimeOffsetSeconds = uint64(60 * 60)
	MedianTimeBlocks     = 11

	PayToWitnessPubKeyHashDataSize = 20
	PayToWitnessScriptHashDataSize = 32
	CoinbaseArbitrarySizeLimit     = 128

	BTMAlias = "BTM"
)

// BTMAssetID is BTM's asset id, the soul asset of Bytom
var BTMAssetID = &bc.AssetID{
	V0: uint64(18446744073709551615),
	V1: uint64(18446744073709551615),
	V2: uint64(18446744073709551615),
	V3: uint64(18446744073709551615),
}

// InitialSeed is SHA3-256 of Byte[0^32]
var InitialSeed = &bc.Hash{
	V0: uint64(11412844483649490393),
	V1: uint64(4614157290180302959),
	V2: uint64(1780246333311066183),
	V3: uint64(9357197556716379726),
}

// BTMDefinitionMap is the ....
var BTMDefinitionMap = map[string]interface{}{
	"name":        BTMAlias,
	"symbol":      BTMAlias,
	"decimals":    8,
	"description": `Bytom Official Issue`,
}

// BlockSubsidy calculate the coinbase rewards on given block height
func BlockSubsidy(height uint64) uint64 {
	if height == 0 {
		return InitialBlockSubsidy
	}
	return baseSubsidy >> uint(height/subsidyReductionInterval)
}

// IsBech32SegwitPrefix returns whether the prefix is a known prefix for segwit
// addresses on any default or registered network.  This is used when decoding
// an address string into a specific address type.
func IsBech32SegwitPrefix(prefix string, params *Params) bool {
	prefix = strings.ToLower(prefix)
	return prefix == params.Bech32HRPSegwit+"1"
}

// Params store the config for different network
type Params struct {
	// Name defines a human-readable identifier for the network.
	Name            string
	Bech32HRPSegwit string
}

// ActiveNetParams is ...
var ActiveNetParams = MainNetParams

// NetParams is the correspondence between chain_id and Params
var NetParams = map[string]Params{
	"mainnet": MainNetParams,
	"testnet": TestNetParams,
	"solonet": SoloNetParams,
}

// MainNetParams is the config for production
var MainNetParams = Params{
	Name:            "main",
	Bech32HRPSegwit: "bm",
}

// TestNetParams is the config for test-net
var TestNetParams = Params{
	Name:            "test",
	Bech32HRPSegwit: "tm",
}

// TestNetParams is the config for test-net
var SoloNetParams = Params{
	Name:            "solo",
	Bech32HRPSegwit: "sm",
}
<|endoftext|>


<commit_before>package handlers

import (
	"log"
	"net"
	"net/http"
	"os"
	"strings"

	"github.com/byuoitav/av-api/base"
	"github.com/byuoitav/av-api/dbo"
	"github.com/byuoitav/av-api/helpers"
	"github.com/byuoitav/av-api/state"
	"github.com/fatih/color"
	"github.com/labstack/echo"
)

func GetRoomState(context echo.Context) error {

	building, room := context.Param("building"), context.Param("room")

	status, err := state.GetRoomState(building, room)
	if err != nil {
		return context.JSON(http.StatusBadRequest, err.Error())
	}

	return context.JSON(http.StatusOK, status)
}

//GetRoomByNameAndBuilding is almost identical to GetRoomByName
func GetRoomByNameAndBuilding(context echo.Context) error {
	log.Printf("Getting room...")
	room, err := dbo.GetRoomByInfo(context.Param("building"), context.Param("room"))
	if err != nil {
		return context.JSON(http.StatusBadRequest, helpers.ReturnError(err))
	}
	log.Printf("Done.\n")
	return context.JSON(http.StatusOK, room)
}

func SetRoomState(context echo.Context) error {
	building, room := context.Param("building"), context.Param("room")
	log.Printf("Putting room changes.\n")

	var roomInQuestion base.PublicRoom
	err := context.Bind(&roomInQuestion)
	if err != nil {
		return context.JSON(http.StatusBadRequest, helpers.ReturnError(err))
	}

	roomInQuestion.Room = room
	roomInQuestion.Building = building

	log.Println("Beginning edit of room state")

	var report base.PublicRoom

	hn, err := net.LookupAddr(context.RealIP())
	color.Set(color.FgYellow, color.Bold)
	if err != nil {
		log.Printf("err %s", err)
		log.Printf("REQUESTOR: %s", context.RealIP())
		color.Unset()
		report, err = state.SetRoomState(roomInQuestion, context.RealIP())
	} else if strings.Contains(hn[0], "localhost") {
		log.Printf("REQUESTOR: %s", os.Getenv("PI_HOSTNAME"))
		color.Unset()
		report, err = state.SetRoomState(roomInQuestion, os.Getenv("PI_HOSTNAME"))
	} else {
		log.Printf("REQUESTOR: %s", hn[0])
		color.Unset()
		report, err = state.SetRoomState(roomInQuestion, hn[0])
	}
	if err != nil {
		log.Printf("Error: %s", err.Error())
		return context.JSON(http.StatusInternalServerError, helpers.ReturnError(err))
	}

	//hasError := helpers.CheckReport(report)

	log.Printf("Done.\n")

	//if hasError {
	//	return context.JSON(http.StatusInternalServerError, report)
	//}

	return context.JSON(http.StatusOK, report)
}
<commit_msg>Director Krennic...<commit_after>package handlers

import (
	"log"
	"net"
	"net/http"
	"os"
	"strings"

	"github.com/byuoitav/av-api/base"
	"github.com/byuoitav/av-api/dbo"
	"github.com/byuoitav/av-api/helpers"
	"github.com/byuoitav/av-api/state"
	"github.com/fatih/color"
	"github.com/labstack/echo"
)

func GetRoomState(context echo.Context) error {

	building, room := context.Param("building"), context.Param("room")

	status, err := state.GetRoomState(building, room)
	if err != nil {
		return context.JSON(http.StatusBadRequest, err.Error())
	}

	return context.JSON(http.StatusOK, status)
}

//GetRoomByNameAndBuilding is almost identical to GetRoomByName
func GetRoomByNameAndBuilding(context echo.Context) error {
	log.Printf("Getting room...")
	room, err := dbo.GetRoomByInfo(context.Param("building"), context.Param("room"))
	if err != nil {
		return context.JSON(http.StatusBadRequest, helpers.ReturnError(err))
	}
	log.Printf("Done.\n")
	return context.JSON(http.StatusOK, room)
}

func SetRoomState(context echo.Context) error {
	building, room := context.Param("building"), context.Param("room")
	log.Printf("%s", color.HiGreenString("[handlers] putting room changes..."))

	var roomInQuestion base.PublicRoom
	err := context.Bind(&roomInQuestion)
	if err != nil {
		return context.JSON(http.StatusBadRequest, helpers.ReturnError(err))
	}

	roomInQuestion.Room = room
	roomInQuestion.Building = building

	log.Println("Beginning edit of room state")

	var report base.PublicRoom

	hn, err := net.LookupAddr(context.RealIP())
	color.Set(color.FgYellow, color.Bold)
	if err != nil {
		log.Printf("err %s", err)
		log.Printf("REQUESTOR: %s", context.RealIP())
		color.Unset()
		report, err = state.SetRoomState(roomInQuestion, context.RealIP())
	} else if strings.Contains(hn[0], "localhost") {
		log.Printf("REQUESTOR: %s", os.Getenv("PI_HOSTNAME"))
		color.Unset()
		report, err = state.SetRoomState(roomInQuestion, os.Getenv("PI_HOSTNAME"))
	} else {
		log.Printf("REQUESTOR: %s", hn[0])
		color.Unset()
		report, err = state.SetRoomState(roomInQuestion, hn[0])
	}
	if err != nil {
		log.Printf("Error: %s", err.Error())
		return context.JSON(http.StatusInternalServerError, helpers.ReturnError(err))
	}

	//hasError := helpers.CheckReport(report)

	log.Printf("Done.\n")

	//if hasError {
	//	return context.JSON(http.StatusInternalServerError, report)
	//}

	return context.JSON(http.StatusOK, report)
}
<|endoftext|>