<commit_before>// Copyright 2015 The etcd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package mvcc

import (
	"sync/atomic"
	"testing"

	"github.com/coreos/etcd/lease"
	"github.com/coreos/etcd/mvcc/backend"
)

type fakeConsistentIndex uint64

func (i *fakeConsistentIndex) ConsistentIndex() uint64 {
	return atomic.LoadUint64((*uint64)(i))
}

func BenchmarkStorePut(b *testing.B) {
	var i fakeConsistentIndex
	be, tmpPath := backend.NewDefaultTmpBackend()
	s := NewStore(be, &lease.FakeLessor{}, &i)
	defer cleanup(s, be, tmpPath)

	// arbitrary number of bytes
	bytesN := 64
	keys := createBytesSlice(bytesN, b.N)
	vals := createBytesSlice(bytesN, b.N)

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		s.Put(keys[i], vals[i], lease.NoLease)
	}
}

// BenchmarkStoreTxnPutUpdate is same as above, but instead updates single key
func BenchmarkStorePutUpdate(b *testing.B) {
	var i fakeConsistentIndex
	be, tmpPath := backend.NewDefaultTmpBackend()
	s := NewStore(be, &lease.FakeLessor{}, &i)
	defer cleanup(s, be, tmpPath)

	// arbitrary number of bytes
	keys := createBytesSlice(64, 1)
	vals := createBytesSlice(1024, 1)

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		s.Put(keys[0], vals[0], lease.NoLease)
	}
}

// BenchmarkStoreTxnPut benchmarks the Put operation
// with transaction begin and end, where transaction involves
// some synchronization operations, such as mutex locking.
func BenchmarkStoreTxnPut(b *testing.B) {
	var i fakeConsistentIndex
	be, tmpPath := backend.NewDefaultTmpBackend()
	s := NewStore(be, &lease.FakeLessor{}, &i)
	defer cleanup(s, be, tmpPath)

	// arbitrary number of bytes
	bytesN := 64
	keys := createBytesSlice(bytesN, b.N)
	vals := createBytesSlice(bytesN, b.N)

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		txn := s.Write()
		txn.Put(keys[i], vals[i], lease.NoLease)
		txn.End()
	}
}

// benchmarkStoreRestore benchmarks the restore operation
func benchmarkStoreRestore(revsPerKey int, b *testing.B) {
	var i fakeConsistentIndex
	be, tmpPath := backend.NewDefaultTmpBackend()
	s := NewStore(be, &lease.FakeLessor{}, &i)
	// use closure to capture 's' to pick up the reassignment
	defer func() { cleanup(s, be, tmpPath) }()

	// arbitrary number of bytes
	bytesN := 64
	keys := createBytesSlice(bytesN, b.N)
	vals := createBytesSlice(bytesN, b.N)

	for i := 0; i < b.N; i++ {
		for j := 0; j < revsPerKey; j++ {
			txn := s.Write()
			txn.Put(keys[i], vals[i], lease.NoLease)
			txn.End()
		}
	}
	s.Close()

	b.ReportAllocs()
	b.ResetTimer()
	s = NewStore(be, &lease.FakeLessor{}, &i)
}

func BenchmarkStoreRestoreRevs1(b *testing.B) {
	benchmarkStoreRestore(1, b)
}

func BenchmarkStoreRestoreRevs10(b *testing.B) {
	benchmarkStoreRestore(10, b)
}

func BenchmarkStoreRestoreRevs20(b *testing.B) {
	benchmarkStoreRestore(20, b)
}
<commit_msg>mvcc: benchmark ConsistentIndex<commit_after>// Copyright 2015 The etcd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package mvcc

import (
	"sync/atomic"
	"testing"

	"github.com/coreos/etcd/lease"
	"github.com/coreos/etcd/mvcc/backend"
)

type fakeConsistentIndex uint64

func (i *fakeConsistentIndex) ConsistentIndex() uint64 {
	return atomic.LoadUint64((*uint64)(i))
}

func BenchmarkStorePut(b *testing.B) {
	var i fakeConsistentIndex
	be, tmpPath := backend.NewDefaultTmpBackend()
	s := NewStore(be, &lease.FakeLessor{}, &i)
	defer cleanup(s, be, tmpPath)

	// arbitrary number of bytes
	bytesN := 64
	keys := createBytesSlice(bytesN, b.N)
	vals := createBytesSlice(bytesN, b.N)

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		s.Put(keys[i], vals[i], lease.NoLease)
	}
}

func BenchmarkConsistentIndex(b *testing.B) {
	fci := fakeConsistentIndex(10)
	be, tmpPath := backend.NewDefaultTmpBackend()
	s := NewStore(be, &lease.FakeLessor{}, &fci)
	defer cleanup(s, be, tmpPath)

	tx := s.b.BatchTx()
	tx.Lock()
	s.saveIndex(tx)
	tx.Unlock()

	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		s.ConsistentIndex()
	}
}

// BenchmarkStoreTxnPutUpdate is same as above, but instead updates single key
func BenchmarkStorePutUpdate(b *testing.B) {
	var i fakeConsistentIndex
	be, tmpPath := backend.NewDefaultTmpBackend()
	s := NewStore(be, &lease.FakeLessor{}, &i)
	defer cleanup(s, be, tmpPath)

	// arbitrary number of bytes
	keys := createBytesSlice(64, 1)
	vals := createBytesSlice(1024, 1)

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		s.Put(keys[0], vals[0], lease.NoLease)
	}
}

// BenchmarkStoreTxnPut benchmarks the Put operation
// with transaction begin and end, where transaction involves
// some synchronization operations, such as mutex locking.
func BenchmarkStoreTxnPut(b *testing.B) {
	var i fakeConsistentIndex
	be, tmpPath := backend.NewDefaultTmpBackend()
	s := NewStore(be, &lease.FakeLessor{}, &i)
	defer cleanup(s, be, tmpPath)

	// arbitrary number of bytes
	bytesN := 64
	keys := createBytesSlice(bytesN, b.N)
	vals := createBytesSlice(bytesN, b.N)

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		txn := s.Write()
		txn.Put(keys[i], vals[i], lease.NoLease)
		txn.End()
	}
}

// benchmarkStoreRestore benchmarks the restore operation
func benchmarkStoreRestore(revsPerKey int, b *testing.B) {
	var i fakeConsistentIndex
	be, tmpPath := backend.NewDefaultTmpBackend()
	s := NewStore(be, &lease.FakeLessor{}, &i)
	// use closure to capture 's' to pick up the reassignment
	defer func() { cleanup(s, be, tmpPath) }()

	// arbitrary number of bytes
	bytesN := 64
	keys := createBytesSlice(bytesN, b.N)
	vals := createBytesSlice(bytesN, b.N)

	for i := 0; i < b.N; i++ {
		for j := 0; j < revsPerKey; j++ {
			txn := s.Write()
			txn.Put(keys[i], vals[i], lease.NoLease)
			txn.End()
		}
	}
	s.Close()

	b.ReportAllocs()
	b.ResetTimer()
	s = NewStore(be, &lease.FakeLessor{}, &i)
}

func BenchmarkStoreRestoreRevs1(b *testing.B) {
	benchmarkStoreRestore(1, b)
}

func BenchmarkStoreRestoreRevs10(b *testing.B) {
	benchmarkStoreRestore(10, b)
}

func BenchmarkStoreRestoreRevs20(b *testing.B) {
	benchmarkStoreRestore(20, b)
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Fission Authors.

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

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

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

package main

import (
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"strings"
	"text/tabwriter"

	"github.com/satori/go.uuid"
	"github.com/urfave/cli"

	"github.com/fission/fission"
)

func fnFetchCode(filePath string) []byte {
	var code []byte
	var err error

	if strings.HasPrefix(filePath, "http://") || strings.HasPrefix(filePath, "https://") {
		var resp *http.Response
		resp, err = http.Get(filePath)
		if err != nil {
			checkErr(err, fmt.Sprintf("download function"))
		}

		defer resp.Body.Close()
		if resp.StatusCode != http.StatusOK {

			err = errors.New(fmt.Sprintf("%v - HTTP response returned non 200 status",
				resp.StatusCode))
			checkErr(err, fmt.Sprintf("download function"))
		}

		code, err = ioutil.ReadAll(resp.Body)
		if err != nil {
			checkErr(err, fmt.Sprintf("download function body %v", filePath))
		}
	} else {
		code, err = ioutil.ReadFile(filePath)
		checkErr(err, fmt.Sprintf("read %v", filePath))
	}
	return code
}

func fnCreate(c *cli.Context) error {
	client := getClient(c.GlobalString("server"))

	fnName := c.String("name")
	if len(fnName) == 0 {
		fatal("Need --name argument.")
	}

	envName := c.String("env")
	if len(envName) == 0 {
		fatal("Need --env argument.")
	}

	fileName := c.String("code")
	if len(fileName) == 0 {
		fatal("Need --code argument.")
	}

	code := fnFetchCode(fileName)

	function := &fission.Function{
		Metadata:    fission.Metadata{Name: fnName},
		Environment: fission.Metadata{Name: envName},
		Code:        string(code),
	}

	_, err := client.FunctionCreate(function)
	checkErr(err, "create function")

	fmt.Printf("function '%v' created\n", fnName)

	// Allow the user to specify an HTTP trigger while creating a function.
	triggerUrl := c.String("url")
	if len(triggerUrl) == 0 {
		return nil
	}
	method := c.String("method")
	if len(method) == 0 {
		method = "GET"
	}
	triggerName := uuid.NewV4().String()
	ht := &fission.HTTPTrigger{
		Metadata: fission.Metadata{
			Name: triggerName,
		},
		UrlPattern: triggerUrl,
		Method:     getMethod(method),
		Function: fission.Metadata{
			Name: fnName,
		},
	}
	_, err = client.HTTPTriggerCreate(ht)
	checkErr(err, "create HTTP trigger")
	fmt.Printf("route created: %v %v -> %v\n", method, triggerUrl, fnName)

	return err
}

func fnGet(c *cli.Context) error {
	client := getClient(c.GlobalString("server"))

	fnName := c.String("name")
	if len(fnName) == 0 {
		fatal("Need name of function, use --name")
	}
	fnUid := c.String("uid")
	m := &fission.Metadata{Name: fnName, Uid: fnUid}

	code, err := client.FunctionGetRaw(m)
	checkErr(err, "get function")

	fmt.Println(string(code))
	return err
}

func fnGetMeta(c *cli.Context) error {
	client := getClient(c.GlobalString("server"))

	fnName := c.String("name")
	fnUid := c.String("uid")
	m := &fission.Metadata{Name: fnName, Uid: fnUid}

	f, err := client.FunctionGet(m)
	checkErr(err, "get function")

	w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
	fmt.Fprintf(w, "%v\t%v\t%v\n", "NAME", "UID", "ENV")
	fmt.Fprintf(w, "%v\t%v\t%v\n",
		f.Metadata.Name, f.Metadata.Uid, f.Environment.Name)
	w.Flush()
	return err
}

func fnUpdate(c *cli.Context) error {
	client := getClient(c.GlobalString("server"))

	fnName := c.String("name")

	function, err := client.FunctionGet(&fission.Metadata{Name: fnName})
	checkErr(err, fmt.Sprintf("read function '%v'", fnName))

	envName := c.String("env")
	if len(envName) > 0 {
		function.Environment.Name = envName
	}

	fileName := c.String("code")
	if len(fileName) > 0 {
		code := fnFetchCode(fileName)

		function.Code = string(code)
	}

	_, err = client.FunctionUpdate(function)
	checkErr(err, "update function")

	fmt.Printf("function '%v' updated\n", fnName)
	return err
}

func fnDelete(c *cli.Context) error {
	client := getClient(c.GlobalString("server"))

	fnName := c.String("name")
	if len(fnName) == 0 {
		fatal("Need name of function, use --name")
	}

	fnUid := c.String("uid")
	m := &fission.Metadata{Name: fnName, Uid: fnUid}

	err := client.FunctionDelete(m)
	checkErr(err, fmt.Sprintf("delete function '%v'", fnName))

	fmt.Printf("function '%v' deleted\n", fnName)
	return err
}

func fnList(c *cli.Context) error {
	client := getClient(c.GlobalString("server"))

	fns, err := client.FunctionList()
	checkErr(err, "list functions")

	w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)

	fmt.Fprintf(w, "%v\t%v\t%v\n", "NAME", "UID", "ENV")
	for _, f := range fns {
		fmt.Fprintf(w, "%v\t%v\t%v\n",
			f.Metadata.Name, f.Metadata.Uid, f.Environment.Name)
	}
	w.Flush()

	return err
}

func fnEdit(c *cli.Context) error {
	client := getClient(c.GlobalString("server"))

	fnName := c.String("name")
	if len(fnName) == 0 {
		fatal("Need name of function, use --name")
	}
	fnUid := c.String("uid")

	// get function meta
	function, err := client.FunctionGet(&fission.Metadata{Name: fnName, Uid: fnUid})
	checkErr(err, fmt.Sprintf("read function '%v'", fnName))

	// write to tmp file
	tmpFile, err := ioutil.TempFile("", fnName)
	checkErr(err, "create temp file")
	defer os.Remove(tmpFile.Name())

	_, err = tmpFile.Write([]byte(function.Code))
	checkErr(err, "write temp file")
	tmpFile.Close()

	// invoke $EDITOR on tmp file and wait for it
	editor := os.Getenv("EDITOR")
	if len(editor) == 0 {
		editor = "vi"
	}
	cmd := exec.Command("/bin/sh", "-c", fmt.Sprintf("%v %v", editor, tmpFile.Name()))
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	err = cmd.Start()
	checkErr(err, "start editor")

	err = cmd.Wait()
	checkErr(err, "wait for editor")

	// read new code out of the file
	contents, err := ioutil.ReadFile(tmpFile.Name())
	checkErr(err, "read temp file")

	function.Code = string(contents)

	// upload the updated function
	newfn, err := client.FunctionUpdate(function)
	checkErr(err, "upload edited function")

	fmt.Printf("function %v updated, new uuid: %v\n", newfn.Name, newfn.Uid)
	return nil
}
<commit_msg>Fixing validations of fn actions<commit_after>/*
Copyright 2016 The Fission Authors.

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

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

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

package main

import (
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"strings"
	"text/tabwriter"

	"github.com/satori/go.uuid"
	"github.com/urfave/cli"

	"github.com/fission/fission"
)

func fnFetchCode(filePath string) []byte {
	var code []byte
	var err error

	if strings.HasPrefix(filePath, "http://") || strings.HasPrefix(filePath, "https://") {
		var resp *http.Response
		resp, err = http.Get(filePath)
		if err != nil {
			checkErr(err, fmt.Sprintf("download function"))
		}

		defer resp.Body.Close()
		if resp.StatusCode != http.StatusOK {

			err = errors.New(fmt.Sprintf("%v - HTTP response returned non 200 status",
				resp.StatusCode))
			checkErr(err, fmt.Sprintf("download function"))
		}

		code, err = ioutil.ReadAll(resp.Body)
		if err != nil {
			checkErr(err, fmt.Sprintf("download function body %v", filePath))
		}
	} else {
		code, err = ioutil.ReadFile(filePath)
		checkErr(err, fmt.Sprintf("read %v", filePath))
	}
	return code
}

func fnCreate(c *cli.Context) error {
	client := getClient(c.GlobalString("server"))

	fnName := c.String("name")
	if len(fnName) == 0 {
		fatal("Need --name argument.")
	}

	envName := c.String("env")
	if len(envName) == 0 {
		fatal("Need --env argument.")
	}

	fileName := c.String("code")
	if len(fileName) == 0 {
		fatal("Need --code argument.")
	}

	code := fnFetchCode(fileName)

	function := &fission.Function{
		Metadata:    fission.Metadata{Name: fnName},
		Environment: fission.Metadata{Name: envName},
		Code:        string(code),
	}

	_, err := client.FunctionCreate(function)
	checkErr(err, "create function")

	fmt.Printf("function '%v' created\n", fnName)

	// Allow the user to specify an HTTP trigger while creating a function.
	triggerUrl := c.String("url")
	if len(triggerUrl) == 0 {
		return nil
	}
	method := c.String("method")
	if len(method) == 0 {
		method = "GET"
	}
	triggerName := uuid.NewV4().String()
	ht := &fission.HTTPTrigger{
		Metadata: fission.Metadata{
			Name: triggerName,
		},
		UrlPattern: triggerUrl,
		Method:     getMethod(method),
		Function: fission.Metadata{
			Name: fnName,
		},
	}
	_, err = client.HTTPTriggerCreate(ht)
	checkErr(err, "create HTTP trigger")
	fmt.Printf("route created: %v %v -> %v\n", method, triggerUrl, fnName)

	return err
}

func fnGet(c *cli.Context) error {
	client := getClient(c.GlobalString("server"))

	fnName := c.String("name")
	if len(fnName) == 0 {
		fatal("Need name of function, use --name")
	}
	fnUid := c.String("uid")
	m := &fission.Metadata{Name: fnName, Uid: fnUid}

	code, err := client.FunctionGetRaw(m)
	checkErr(err, "get function")

	fmt.Println(string(code))
	return err
}

func fnGetMeta(c *cli.Context) error {
	client := getClient(c.GlobalString("server"))

	fnName := c.String("name")
	if len(fnName) == 0 {
		fatal("Need name of function, use --name")
	}

	fnUid := c.String("uid")
	m := &fission.Metadata{Name: fnName, Uid: fnUid}

	f, err := client.FunctionGet(m)
	checkErr(err, "get function")

	w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
	fmt.Fprintf(w, "%v\t%v\t%v\n", "NAME", "UID", "ENV")
	fmt.Fprintf(w, "%v\t%v\t%v\n",
		f.Metadata.Name, f.Metadata.Uid, f.Environment.Name)
	w.Flush()
	return err
}

func fnUpdate(c *cli.Context) error {
	client := getClient(c.GlobalString("server"))

	fnName := c.String("name")
	if len(fnName) == 0 {
		fatal("Need name of function, use --name")
	}

	function, err := client.FunctionGet(&fission.Metadata{Name: fnName})
	checkErr(err, fmt.Sprintf("read function '%v'", fnName))

	envName := c.String("env")
	if len(envName) > 0 {
		function.Environment.Name = envName
	}

	fileName := c.String("code")
	if len(fileName) > 0 {
		code := fnFetchCode(fileName)

		function.Code = string(code)
	}

	_, err = client.FunctionUpdate(function)
	checkErr(err, "update function")

	fmt.Printf("function '%v' updated\n", fnName)
	return err
}

func fnDelete(c *cli.Context) error {
	client := getClient(c.GlobalString("server"))

	fnName := c.String("name")
	if len(fnName) == 0 {
		fatal("Need name of function, use --name")
	}

	fnUid := c.String("uid")
	m := &fission.Metadata{Name: fnName, Uid: fnUid}

	err := client.FunctionDelete(m)
	checkErr(err, fmt.Sprintf("delete function '%v'", fnName))

	fmt.Printf("function '%v' deleted\n", fnName)
	return err
}

func fnList(c *cli.Context) error {
	client := getClient(c.GlobalString("server"))

	fns, err := client.FunctionList()
	checkErr(err, "list functions")

	w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)

	fmt.Fprintf(w, "%v\t%v\t%v\n", "NAME", "UID", "ENV")
	for _, f := range fns {
		fmt.Fprintf(w, "%v\t%v\t%v\n",
			f.Metadata.Name, f.Metadata.Uid, f.Environment.Name)
	}
	w.Flush()

	return err
}

func fnEdit(c *cli.Context) error {
	client := getClient(c.GlobalString("server"))

	fnName := c.String("name")
	if len(fnName) == 0 {
		fatal("Need name of function, use --name")
	}
	fnUid := c.String("uid")

	// get function meta
	function, err := client.FunctionGet(&fission.Metadata{Name: fnName, Uid: fnUid})
	checkErr(err, fmt.Sprintf("read function '%v'", fnName))

	// write to tmp file
	tmpFile, err := ioutil.TempFile("", fnName)
	checkErr(err, "create temp file")
	defer os.Remove(tmpFile.Name())

	_, err = tmpFile.Write([]byte(function.Code))
	checkErr(err, "write temp file")
	tmpFile.Close()

	// invoke $EDITOR on tmp file and wait for it
	editor := os.Getenv("EDITOR")
	if len(editor) == 0 {
		editor = "vi"
	}
	cmd := exec.Command("/bin/sh", "-c", fmt.Sprintf("%v %v", editor, tmpFile.Name()))
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	err = cmd.Start()
	checkErr(err, "start editor")

	err = cmd.Wait()
	checkErr(err, "wait for editor")

	// read new code out of the file
	contents, err := ioutil.ReadFile(tmpFile.Name())
	checkErr(err, "read temp file")

	function.Code = string(contents)

	// upload the updated function
	newfn, err := client.FunctionUpdate(function)
	checkErr(err, "upload edited function")

	fmt.Printf("function %v updated, new uuid: %v\n", newfn.Name, newfn.Uid)
	return nil
}
<|endoftext|>


<commit_before>// Copyright 2012 Dmitry Chestnykh   (Go implementation)
// Copyright 2009 Colin Percival     (original C implementation)
// All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package scrypt implements the scrypt key derivation function as defined in
// Colin Percival's paper "Stronger Key Derivation via Sequential Memory-Hard
// Functions".
package scrypt

import (
	"crypto/sha256"
	"encoding/binary"
	"errors"

	"code.google.com/p/go.crypto/pbkdf2"
)

const maxInt = 1<<31 - 1

// blockCopy copies n bytes from src into dst.
func blockCopy(dst, src []byte, n int) {
	copy(dst, src[:n])
}

// blockXOR XORs bytes from dst with n bytes from src.
func blockXOR(dst, src []byte, n int) {
	for i, v := range src[:n] {
		dst[i] ^= v
	}
}

// salsa applies Salsa20/8 to the given 64-byte slice.
func salsa(b []byte) {
	var w [16]uint32

	for i := 0; i < 16; i++ {
		j := i * 4
		w[i] = uint32(b[j]) | uint32(b[j+1])<<8 | uint32(b[j+2])<<16 | uint32(b[j+3])<<24
	}

	x0, x1, x2, x3, x4, x5, x6, x7, x8 := w[0], w[1], w[2], w[3], w[4], w[5], w[6], w[7], w[8]
	x9, x10, x11, x12, x13, x14, x15 := w[9], w[10], w[11], w[12], w[13], w[14], w[15]

	for i := 0; i < 8; i += 2 {
		u := x0 + x12
		x4 ^= u<<7 | u>>(32-7)
		u = x4 + x0
		x8 ^= u<<9 | u>>(32-9)
		u = x8 + x4
		x12 ^= u<<13 | u>>(32-13)
		u = x12 + x8
		x0 ^= u<<18 | u>>(32-18)

		u = x5 + x1
		x9 ^= u<<7 | u>>(32-7)
		u = x9 + x5
		x13 ^= u<<9 | u>>(32-9)
		u = x13 + x9
		x1 ^= u<<13 | u>>(32-13)
		u = x1 + x13
		x5 ^= u<<18 | u>>(32-18)

		u = x10 + x6
		x14 ^= u<<7 | u>>(32-7)
		u = x14 + x10
		x2 ^= u<<9 | u>>(32-9)
		u = x2 + x14
		x6 ^= u<<13 | u>>(32-13)
		u = x6 + x2
		x10 ^= u<<18 | u>>(32-18)

		u = x15 + x11
		x3 ^= u<<7 | u>>(32-7)
		u = x3 + x15
		x7 ^= u<<9 | u>>(32-9)
		u = x7 + x3
		x11 ^= u<<13 | u>>(32-13)
		u = x11 + x7
		x15 ^= u<<18 | u>>(32-18)

		u = x0 + x3
		x1 ^= u<<7 | u>>(32-7)
		u = x1 + x0
		x2 ^= u<<9 | u>>(32-9)
		u = x2 + x1
		x3 ^= u<<13 | u>>(32-13)
		u = x3 + x2
		x0 ^= u<<18 | u>>(32-18)

		u = x5 + x4
		x6 ^= u<<7 | u>>(32-7)
		u = x6 + x5
		x7 ^= u<<9 | u>>(32-9)
		u = x7 + x6
		x4 ^= u<<13 | u>>(32-13)
		u = x4 + x7
		x5 ^= u<<18 | u>>(32-18)

		u = x10 + x9
		x11 ^= u<<7 | u>>(32-7)
		u = x11 + x10
		x8 ^= u<<9 | u>>(32-9)
		u = x8 + x11
		x9 ^= u<<13 | u>>(32-13)
		u = x9 + x8
		x10 ^= u<<18 | u>>(32-18)

		u = x15 + x14
		x12 ^= u<<7 | u>>(32-7)
		u = x12 + x15
		x13 ^= u<<9 | u>>(32-9)
		u = x13 + x12
		x14 ^= u<<13 | u>>(32-13)
		u = x14 + x13
		x15 ^= u<<18 | u>>(32-18)
	}
	w[0] += x0
	w[1] += x1
	w[2] += x2
	w[3] += x3
	w[4] += x4
	w[5] += x5
	w[6] += x6
	w[7] += x7
	w[8] += x8
	w[9] += x9
	w[10] += x10
	w[11] += x11
	w[12] += x12
	w[13] += x13
	w[14] += x14
	w[15] += x15

	j := 0
	for _, v := range w {
		b[j+0] = byte(v >> 0)
		b[j+1] = byte(v >> 8)
		b[j+2] = byte(v >> 16)
		b[j+3] = byte(v >> 24)
		j += 4
	}
}

func blockMix(b, y []byte, r int) {
	x := make([]byte, 64)

	blockCopy(x, b[(2*r-1)*64:], 64)

	for i := 0; i < 2*r; i++ {
		blockXOR(x, b[i*64:], 64)
		salsa(x)

		blockCopy(y[i*64:], x, 64)
	}

	for i := 0; i < r; i++ {
		blockCopy(b[i*64:], y[(i*2)*64:], 64)
	}

	for i := 0; i < r; i++ {
		blockCopy(b[(i+r)*64:], y[(i*2+1)*64:], 64)
	}
}

func integerify(b []byte, r int) uint64 {
	return binary.LittleEndian.Uint64(b[(2*r-1)*64:])
}

func smix(b []byte, r, N int, v, xy []byte) {
	x := xy
	y := xy[128*r:]

	blockCopy(x, b, 128*r)

	for i := 0; i < N; i++ {
		blockCopy(v[i*(128*r):], x, 128*r)
		blockMix(x, y, r)
	}

	for i := 0; i < N; i++ {
		j := int(integerify(x, r) & uint64(N-1))
		blockXOR(x, v[j*(128*r):], 128*r)
		blockMix(x, y, r)
	}

	blockCopy(b, x, 128*r)
}

// Key derives a key from the password, salt and cost parameters, returning a
// byte slice of length keyLen that can be used as cryptographic key.
//
// N is a CPU/memory cost parameter, must be a power of two greater than 1.
// r and p must satisfy r * p < 2³⁰. If the parameters do not satisfy the
// limits, the function returns a nil byte slice and an error.
//
// For example, you can get a derived key for e.g. AES-256 (which needs a
// 32-byte key) by doing:
//
//      dk := scrypt.Key([]byte("some password"), salt, 16384, 8, 1, 32)
//
// The recommended parameters for interactive logins as of 2009 are N=16384,
// r=8, p=1. They should be increased as memory latency and CPU parallelism
// increases. Remember to get a good random salt.
func Key(password, salt []byte, N, r, p, keyLen int) ([]byte, error) {
	if N <= 1 || N&(N-1) != 0 {
		return nil, errors.New("scrypt: N must be > 1 and a power of 2")
	}
	if uint64(r)*uint64(p) >= 1<<30 || r > maxInt/128/p || r > maxInt/256 || N > maxInt/128/r {
		return nil, errors.New("scrypt: parameters are too large")
	}

	xy := make([]byte, 256*r)
	v := make([]byte, 128*r*N)
	b := pbkdf2.Key(password, salt, 1, p*128*r, sha256.New)

	for i := 0; i < p; i++ {
		smix(b[i*128*r:], r, N, v, xy)
	}

	return pbkdf2.Key(password, b, 1, keyLen, sha256.New), nil
}
<commit_msg>Use variables instead of array in Salsa20.<commit_after>// Copyright 2012 Dmitry Chestnykh   (Go implementation)
// Copyright 2009 Colin Percival     (original C implementation)
// All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package scrypt implements the scrypt key derivation function as defined in
// Colin Percival's paper "Stronger Key Derivation via Sequential Memory-Hard
// Functions".
package scrypt

import (
	"crypto/sha256"
	"encoding/binary"
	"errors"

	"code.google.com/p/go.crypto/pbkdf2"
)

const maxInt = 1<<31 - 1

// blockCopy copies n bytes from src into dst.
func blockCopy(dst, src []byte, n int) {
	copy(dst, src[:n])
}

// blockXOR XORs bytes from dst with n bytes from src.
func blockXOR(dst, src []byte, n int) {
	for i, v := range src[:n] {
		dst[i] ^= v
	}
}

// salsa applies Salsa20/8 to the given 64-byte slice.
func salsa(b []byte) {
	w0 := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
	w1 := uint32(b[4]) | uint32(b[5])<<8 | uint32(b[6])<<16 | uint32(b[7])<<24
	w2 := uint32(b[8]) | uint32(b[9])<<8 | uint32(b[10])<<16 | uint32(b[11])<<24
	w3 := uint32(b[12]) | uint32(b[13])<<8 | uint32(b[14])<<16 | uint32(b[15])<<24
	w4 := uint32(b[16]) | uint32(b[17])<<8 | uint32(b[18])<<16 | uint32(b[19])<<24
	w5 := uint32(b[20]) | uint32(b[21])<<8 | uint32(b[22])<<16 | uint32(b[23])<<24
	w6 := uint32(b[24]) | uint32(b[25])<<8 | uint32(b[26])<<16 | uint32(b[27])<<24
	w7 := uint32(b[28]) | uint32(b[29])<<8 | uint32(b[30])<<16 | uint32(b[31])<<24
	w8 := uint32(b[32]) | uint32(b[33])<<8 | uint32(b[34])<<16 | uint32(b[35])<<24
	w9 := uint32(b[36]) | uint32(b[37])<<8 | uint32(b[38])<<16 | uint32(b[39])<<24
	w10 := uint32(b[40]) | uint32(b[41])<<8 | uint32(b[42])<<16 | uint32(b[43])<<24
	w11 := uint32(b[44]) | uint32(b[45])<<8 | uint32(b[46])<<16 | uint32(b[47])<<24
	w12 := uint32(b[48]) | uint32(b[49])<<8 | uint32(b[50])<<16 | uint32(b[51])<<24
	w13 := uint32(b[52]) | uint32(b[53])<<8 | uint32(b[54])<<16 | uint32(b[55])<<24
	w14 := uint32(b[56]) | uint32(b[57])<<8 | uint32(b[58])<<16 | uint32(b[59])<<24
	w15 := uint32(b[60]) | uint32(b[61])<<8 | uint32(b[62])<<16 | uint32(b[63])<<24

	x0, x1, x2, x3, x4, x5, x6, x7, x8 := w0, w1, w2, w3, w4, w5, w6, w7, w8
	x9, x10, x11, x12, x13, x14, x15 := w9, w10, w11, w12, w13, w14, w15

	for i := 0; i < 8; i += 2 {
		u := x0 + x12
		x4 ^= u<<7 | u>>(32-7)
		u = x4 + x0
		x8 ^= u<<9 | u>>(32-9)
		u = x8 + x4
		x12 ^= u<<13 | u>>(32-13)
		u = x12 + x8
		x0 ^= u<<18 | u>>(32-18)

		u = x5 + x1
		x9 ^= u<<7 | u>>(32-7)
		u = x9 + x5
		x13 ^= u<<9 | u>>(32-9)
		u = x13 + x9
		x1 ^= u<<13 | u>>(32-13)
		u = x1 + x13
		x5 ^= u<<18 | u>>(32-18)

		u = x10 + x6
		x14 ^= u<<7 | u>>(32-7)
		u = x14 + x10
		x2 ^= u<<9 | u>>(32-9)
		u = x2 + x14
		x6 ^= u<<13 | u>>(32-13)
		u = x6 + x2
		x10 ^= u<<18 | u>>(32-18)

		u = x15 + x11
		x3 ^= u<<7 | u>>(32-7)
		u = x3 + x15
		x7 ^= u<<9 | u>>(32-9)
		u = x7 + x3
		x11 ^= u<<13 | u>>(32-13)
		u = x11 + x7
		x15 ^= u<<18 | u>>(32-18)

		u = x0 + x3
		x1 ^= u<<7 | u>>(32-7)
		u = x1 + x0
		x2 ^= u<<9 | u>>(32-9)
		u = x2 + x1
		x3 ^= u<<13 | u>>(32-13)
		u = x3 + x2
		x0 ^= u<<18 | u>>(32-18)

		u = x5 + x4
		x6 ^= u<<7 | u>>(32-7)
		u = x6 + x5
		x7 ^= u<<9 | u>>(32-9)
		u = x7 + x6
		x4 ^= u<<13 | u>>(32-13)
		u = x4 + x7
		x5 ^= u<<18 | u>>(32-18)

		u = x10 + x9
		x11 ^= u<<7 | u>>(32-7)
		u = x11 + x10
		x8 ^= u<<9 | u>>(32-9)
		u = x8 + x11
		x9 ^= u<<13 | u>>(32-13)
		u = x9 + x8
		x10 ^= u<<18 | u>>(32-18)

		u = x15 + x14
		x12 ^= u<<7 | u>>(32-7)
		u = x12 + x15
		x13 ^= u<<9 | u>>(32-9)
		u = x13 + x12
		x14 ^= u<<13 | u>>(32-13)
		u = x14 + x13
		x15 ^= u<<18 | u>>(32-18)
	}
	x0 += w0
	x1 += w1
	x2 += w2
	x3 += w3
	x4 += w4
	x5 += w5
	x6 += w6
	x7 += w7
	x8 += w8
	x9 += w9
	x10 += w10
	x11 += w11
	x12 += w12
	x13 += w13
	x14 += w14
	x15 += w15

	b[0], b[1], b[2], b[3] = byte(x0), byte(x0>>8), byte(x0>>16), byte(x0>>24)
	b[4], b[5], b[6], b[7] = byte(x1), byte(x1>>8), byte(x1>>16), byte(x1>>24)
	b[8], b[9], b[10], b[11] = byte(x2), byte(x2>>8), byte(x2>>16), byte(x2>>24)
	b[12], b[13], b[14], b[15] = byte(x3), byte(x3>>8), byte(x3>>16), byte(x3>>24)
	b[16], b[17], b[18], b[19] = byte(x4), byte(x4>>8), byte(x4>>16), byte(x4>>24)
	b[20], b[21], b[22], b[23] = byte(x5), byte(x5>>8), byte(x5>>16), byte(x5>>24)
	b[24], b[25], b[26], b[27] = byte(x6), byte(x6>>8), byte(x6>>16), byte(x6>>24)
	b[28], b[29], b[30], b[31] = byte(x7), byte(x7>>8), byte(x7>>16), byte(x7>>24)
	b[32], b[33], b[34], b[35] = byte(x8), byte(x8>>8), byte(x8>>16), byte(x8>>24)
	b[36], b[37], b[38], b[39] = byte(x9), byte(x9>>8), byte(x9>>16), byte(x9>>24)
	b[40], b[41], b[42], b[43] = byte(x10), byte(x10>>8), byte(x10>>16), byte(x10>>24)
	b[44], b[45], b[46], b[47] = byte(x11), byte(x11>>8), byte(x11>>16), byte(x11>>24)
	b[48], b[49], b[50], b[51] = byte(x12), byte(x12>>8), byte(x12>>16), byte(x12>>24)
	b[52], b[53], b[54], b[55] = byte(x13), byte(x13>>8), byte(x13>>16), byte(x13>>24)
	b[56], b[57], b[58], b[59] = byte(x14), byte(x14>>8), byte(x14>>16), byte(x14>>24)
	b[60], b[61], b[62], b[63] = byte(x15), byte(x15>>8), byte(x15>>16), byte(x15>>24)
}

func blockMix(b, y []byte, r int) {
	x := make([]byte, 64)

	blockCopy(x, b[(2*r-1)*64:], 64)

	for i := 0; i < 2*r; i++ {
		blockXOR(x, b[i*64:], 64)
		salsa(x)

		blockCopy(y[i*64:], x, 64)
	}

	for i := 0; i < r; i++ {
		blockCopy(b[i*64:], y[(i*2)*64:], 64)
	}

	for i := 0; i < r; i++ {
		blockCopy(b[(i+r)*64:], y[(i*2+1)*64:], 64)
	}
}

func integerify(b []byte, r int) uint64 {
	return binary.LittleEndian.Uint64(b[(2*r-1)*64:])
}

func smix(b []byte, r, N int, v, xy []byte) {
	x := xy
	y := xy[128*r:]

	blockCopy(x, b, 128*r)

	for i := 0; i < N; i++ {
		blockCopy(v[i*(128*r):], x, 128*r)
		blockMix(x, y, r)
	}

	for i := 0; i < N; i++ {
		j := int(integerify(x, r) & uint64(N-1))
		blockXOR(x, v[j*(128*r):], 128*r)
		blockMix(x, y, r)
	}

	blockCopy(b, x, 128*r)
}

// Key derives a key from the password, salt and cost parameters, returning a
// byte slice of length keyLen that can be used as cryptographic key.
//
// N is a CPU/memory cost parameter, must be a power of two greater than 1.
// r and p must satisfy r * p < 2³⁰. If the parameters do not satisfy the
// limits, the function returns a nil byte slice and an error.
//
// For example, you can get a derived key for e.g. AES-256 (which needs a
// 32-byte key) by doing:
//
//      dk := scrypt.Key([]byte("some password"), salt, 16384, 8, 1, 32)
//
// The recommended parameters for interactive logins as of 2009 are N=16384,
// r=8, p=1. They should be increased as memory latency and CPU parallelism
// increases. Remember to get a good random salt.
func Key(password, salt []byte, N, r, p, keyLen int) ([]byte, error) {
	if N <= 1 || N&(N-1) != 0 {
		return nil, errors.New("scrypt: N must be > 1 and a power of 2")
	}
	if uint64(r)*uint64(p) >= 1<<30 || r > maxInt/128/p || r > maxInt/256 || N > maxInt/128/r {
		return nil, errors.New("scrypt: parameters are too large")
	}

	xy := make([]byte, 256*r)
	v := make([]byte, 128*r*N)
	b := pbkdf2.Key(password, salt, 1, p*128*r, sha256.New)

	for i := 0; i < p; i++ {
		smix(b[i*128*r:], r, N, v, xy)
	}

	return pbkdf2.Key(password, b, 1, keyLen, sha256.New), nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"net/http"
	"os"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/prometheus/common/log"
	"github.com/prometheus/common/version"

	"crypto/tls"
	"encoding/json"
	"io/ioutil"
	"sync"
)

const (
	namespace = "fluentd" //for Prometheus metrics.
)

// declare variables for fluentd metrics
var (
	listeningAddress = flag.String("telementry.address", ":9117", "Address on which to expose metrics.")
	metricsEndpoint  = flag.String("Telementry.endpoint", "/metrics", "Path under which to expose metric.")
	scrapeURI        = flag.String("scrape_uri", "http://localhost:24220/api/plugins.json", "URI to fluentd metrics")
	insecure         = flag.Bool("insecure", false, "Ignore server certificate if using https, Default: false.")
	showVersion      = flag.Bool("version", false, "Print version information.")
)

type Exporter struct {
	URI    string
	mutex  sync.Mutex
	client *http.Client

	up *prometheus.Desc
	bufferQueueLength *prometheus.Desc
	bufferTotalQueuedSize *prometheus.Desc
	retryCount            *prometheus.Desc

	pluginId map[string]*prometheus.Desc
}

// NewExporter returns an initialized Exporter.

func NewExporter(uri string) *Exporter {
	return &Exporter{
		URI: uri,
		up: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, "", "up"),
			"Could fluentd be reached",
			nil,
			nil),
		bufferQueueLength: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, "", "buffer_queue_length"),
			"Buffered queue length",
			[]string{"pluginId", "pluginCategory"},
			nil),
		bufferTotalQueuedSize: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, "", "buffer_queued_size"),
			"size of the total queued",
			[]string{"pluginId", "pluginCategory"},
			nil),
		retryCount: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, "", "retry"),
			"fluentd retry count",
			[]string{"pluginId", "pluginCategory"},
			nil),
		client: &http.Client{
			Transport: &http.Transport{
				TLSClientConfig: &tls.Config{InsecureSkipVerify: *insecure},
			},
		},
	}
}

// Describe describes all the metrics ever exported by the fluentd exporter. It
// implements prometheus.Collector.
func (e *Exporter) Describe(ch chan<- *prometheus.Desc) {
	ch <- e.bufferQueueLength
	ch <- e.bufferTotalQueuedSize
	ch <- e.retryCount
}

// json data structure for fluentd
type jsonData struct {
	Plugins []struct {
		PluginID              string `json:"plugin_id"`
		PluginCategory        string `json:"plugin_category"`
		Type                  string `json:"type"`
		RetryCount            int    `json:"retry_count"`
		BufferQueueLength     int    `json:"buffer_queue_length,omitempty"`
		BufferTotalQueuedSize int    `json:"buffer_total_queued_size,omitempty"`
	} `json:"plugins"`
}

// Collect fetches the stats from configured location and delivers them
// as Prometheus metrics.
// It implements prometheus.Collector.
func (e *Exporter) collect(ch chan<- prometheus.Metric) error {
	resp, err := e.client.Get(e.URI)
	if err != nil {
		ch <- prometheus.MustNewConstMetric(e.up, prometheus.GaugeValue, 0)
		return fmt.Errorf("Error scraping fluentd: %v", err)
	}
	ch <- prometheus.MustNewConstMetric(e.up, prometheus.GaugeValue, 1)

	// get data from body of response and check if there was a read error
	body, readErr := ioutil.ReadAll(resp.Body)
	if readErr != nil {
		log.Fatal(readErr)
	}

	// close connection
	resp.Body.Close()
	if resp.StatusCode != 200 {
		fmt.Println("There was an error")
		return fmt.Errorf("Status %s (%d)", resp.Status, resp.StatusCode)
	}

	//init struct for unmarshal and check that there was no unmarshalling error
	jdata := jsonData{}
	jError := json.Unmarshal(body, &jdata)
	if jError != nil {
		log.Fatal(jError)
	}

	// organise json response and map to created metrics
	//parse through json response from fluentd
	for _, plugin := range jdata.Plugins {
		if plugin.PluginCategory == "input" {
			continue
		}
		ch <- prometheus.MustNewConstMetric(e.bufferQueueLength, prometheus.CounterValue, float64(plugin.BufferQueueLength), plugin.PluginID, plugin.PluginCategory)
		ch <- prometheus.MustNewConstMetric(e.bufferTotalQueuedSize, prometheus.CounterValue, float64(plugin.BufferTotalQueuedSize), plugin.PluginID, plugin.PluginCategory)
		ch <- prometheus.MustNewConstMetric(e.retryCount, prometheus.CounterValue, float64(plugin.RetryCount), plugin.PluginID, plugin.PluginCategory)
	}

	return nil
}

// Collect fetches the stats from configured fluentd location and delivers them
// as Prometheus metrics.
// It implements prometheus.Collector.
func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
	e.mutex.Lock() // To protect metrics from concurrent collects.
	defer e.mutex.Unlock()
	if err := e.collect(ch); err != nil {
		log.Errorf("Error scraping fluentd: %s", err)
	}
	return
}

func main() {
	flag.Parse()

	if *showVersion {
		fmt.Fprintln(os.Stdout, version.Print("fluentd_exporter"))
		os.Exit(0)
	}

	exporter := NewExporter(*scrapeURI)

	prometheus.MustRegister(exporter)
	prometheus.MustRegister(version.NewCollector("fluentd_exporter"))

	log.Infoln("Starting fluentd_exporter", version.Info())
	log.Infoln("Build context", version.BuildContext())

	log.Infof("Starting Server: %s", *listeningAddress)
	http.Handle(*metricsEndpoint, promhttp.Handler())
	log.Fatal(http.ListenAndServe(*listeningAddress, nil))
}
<commit_msg>updated matrix alias and changed bufferQueueLength to gauge type<commit_after>package main

import (
	"flag"
	"fmt"
	"net/http"
	"os"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/prometheus/common/log"
	"github.com/prometheus/common/version"

	"crypto/tls"
	"encoding/json"
	"io/ioutil"
	"sync"
)

const (
	namespace = "fluentd" //for Prometheus metrics.
)

// declare variables for fluentd metrics
var (
	listeningAddress = flag.String("telementry.address", ":9117", "Address on which to expose metrics.")
	metricsEndpoint  = flag.String("Telementry.endpoint", "/metrics", "Path under which to expose metric.")
	scrapeURI        = flag.String("scrape_uri", "http://localhost:24220/api/plugins.json", "URI to fluentd metrics")
	insecure         = flag.Bool("insecure", false, "Ignore server certificate if using https, Default: false.")
	showVersion      = flag.Bool("version", false, "Print version information.")
)

type Exporter struct {
	URI    string
	mutex  sync.Mutex
	client *http.Client

	up *prometheus.Desc
	bufferQueueLength *prometheus.Desc
	bufferTotalQueuedSize *prometheus.Desc
	retryCount            *prometheus.Desc

	pluginId map[string]*prometheus.Desc
}

// NewExporter returns an initialized Exporter.

func NewExporter(uri string) *Exporter {
	return &Exporter{
		URI: uri,
		up: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, "", "up"),
			"Could fluentd be reached",
			nil,
			nil),
		bufferQueueLength: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, "", "buffer_queue_length"),
			"Buffered queue length",
			[]string{"pluginId", "pluginCategory"},
			nil),
		bufferTotalQueuedSize: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, "", "buffer_queued_size"),
			"size of the total queued",
			[]string{"pluginId", "pluginCategory"},
			nil),
		retryCount: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, "", "retry_total"),
			"fluentd retry count",
			[]string{"pluginId", "pluginCategory"},
			nil),
		client: &http.Client{
			Transport: &http.Transport{
				TLSClientConfig: &tls.Config{InsecureSkipVerify: *insecure},
			},
		},
	}
}

// Describe describes all the metrics ever exported by the fluentd exporter. It
// implements prometheus.Collector.
func (e *Exporter) Describe(ch chan<- *prometheus.Desc) {
	ch <- e.bufferQueueLength
	ch <- e.bufferTotalQueuedSize
	ch <- e.retryCount
}

// json data structure for fluentd
type jsonData struct {
	Plugins []struct {
		PluginID              string `json:"plugin_id"`
		PluginCategory        string `json:"plugin_category"`
		Type                  string `json:"type"`
		RetryCount            int    `json:"retry_count"`
		BufferQueueLength     int    `json:"buffer_queue_length,omitempty"`
		BufferTotalQueuedSize int    `json:"buffer_total_queued_size,omitempty"`
	} `json:"plugins"`
}

// Collect fetches the stats from configured location and delivers them
// as Prometheus metrics.
// It implements prometheus.Collector.
func (e *Exporter) collect(ch chan<- prometheus.Metric) error {
	resp, err := e.client.Get(e.URI)
	if err != nil {
		ch <- prometheus.MustNewConstMetric(e.up, prometheus.GaugeValue, 0)
		return fmt.Errorf("Error scraping fluentd: %v", err)
	}
	ch <- prometheus.MustNewConstMetric(e.up, prometheus.GaugeValue, 1)

	// get data from body of response and check if there was a read error
	body, readErr := ioutil.ReadAll(resp.Body)
	if readErr != nil {
		log.Fatal(readErr)
	}

	// close connection
	resp.Body.Close()
	if resp.StatusCode != 200 {
		fmt.Println("There was an error")
		return fmt.Errorf("Status %s (%d)", resp.Status, resp.StatusCode)
	}

	//init struct for unmarshal and check that there was no unmarshalling error
	jdata := jsonData{}
	jError := json.Unmarshal(body, &jdata)
	if jError != nil {
		log.Fatal(jError)
	}

	// organise json response and map to created metrics
	//parse through json response from fluentd
	for _, plugin := range jdata.Plugins {
		if plugin.PluginCategory == "input" {
			continue
		}
		ch <- prometheus.MustNewConstMetric(e.bufferQueueLength, prometheus.GaugeValue, float64(plugin.BufferQueueLength), plugin.PluginID, plugin.PluginCategory)
		ch <- prometheus.MustNewConstMetric(e.bufferTotalQueuedSize, prometheus.CounterValue, float64(plugin.BufferTotalQueuedSize), plugin.PluginID, plugin.PluginCategory)
		ch <- prometheus.MustNewConstMetric(e.retryCount, prometheus.CounterValue, float64(plugin.RetryCount), plugin.PluginID, plugin.PluginCategory)
	}

	return nil
}

// Collect fetches the stats from configured fluentd location and delivers them
// as Prometheus metrics.
// It implements prometheus.Collector.
func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
	e.mutex.Lock() // To protect metrics from concurrent collects.
	defer e.mutex.Unlock()
	if err := e.collect(ch); err != nil {
		log.Errorf("Error scraping fluentd: %s", err)
	}
	return
}

func main() {
	flag.Parse()

	if *showVersion {
		fmt.Fprintln(os.Stdout, version.Print("fluentd_exporter"))
		os.Exit(0)
	}

	exporter := NewExporter(*scrapeURI)

	prometheus.MustRegister(exporter)
	prometheus.MustRegister(version.NewCollector("fluentd_exporter"))

	log.Infoln("Starting fluentd_exporter", version.Info())
	log.Infoln("Build context", version.BuildContext())

	log.Infof("Starting Server: %s", *listeningAddress)
	http.Handle(*metricsEndpoint, promhttp.Handler())
	log.Fatal(http.ListenAndServe(*listeningAddress, nil))
}
<|endoftext|>


<commit_before>package formatter

import (
	"fmt"
	ui "github.com/gizak/termui"
	tm "github.com/nsf/termbox-go"
	"os"
	"strconv"
	"time"
)

// WindowFormatter shows Outputs with termui
type WindowFormatter struct {
	widgets       map[string]ui.GridBufferer
	machineWidets []ui.Bufferer
	machineOutput []*Output
	machineCount  int
	headerYShift  int
	event         chan tm.Event
	list          []string
	progress      float64
	step          float64
	selectedIndex int
	pageSize      int
	selectedPage  int
	*abstractFormatter
}

// NewWindowFormatter initializes a WindowFormatter, and starts it.
func NewWindowFormatter() *WindowFormatter {
	bf := newAbstractFormatter()
	count := len(bf.hosts())
	wf := &WindowFormatter{
		widgets:       make(map[string]ui.GridBufferer),
		machineWidets: make([]ui.Bufferer, 0, count),
		machineOutput: make([]*Output, 0, count),
		machineCount:  count,
		event:         make(chan tm.Event),
		list:          make([]string, 0, count),
		progress:      0,
		step:          100 / float64(count),
		selectedIndex: 0,
		selectedPage:  0,
	}
	wf.abstractFormatter = bf
	err := ui.Init()
	if err != nil {
		panic(err)
	}
	ui.UseTheme("helloworld")

	// Footer
	// help Box
	helpWidget := ui.NewPar("q:QUIT; j:DOWN; k:UP")
	helpWidget.Height = 3
	helpWidget.Border.Label = "HELP"
	helpWidget.Border.FgColor = ui.ColorCyan
	helpWidget.TextFgColor = ui.ColorWhite
	wf.widgets["help"] = helpWidget
	// Header
	// progess Gauge
	headerHeight := 3
	gauge := ui.NewGauge()
	gauge.Height = headerHeight
	gauge.Percent = 0
	gauge.Border.Label = "PROGRESS"
	gauge.Border.FgColor = ui.ColorCyan
	gauge.BarColor = ui.ColorGreen
	wf.widgets["progress"] = gauge
	wf.headerYShift = gauge.Height + 1
	// info Textbox
	infoText := fmt.Sprintf("USER : %s", info.User)
	infoWidget := ui.NewPar(infoText)
	infoWidget.Height = headerHeight
	if info.User == "root" {
		infoWidget.Border.FgColor = ui.ColorRed
		infoWidget.TextFgColor = ui.ColorRed
		infoWidget.TextBgColor = ui.ColorWhite
	} else {
		infoWidget.Border.FgColor = ui.ColorCyan
		infoWidget.TextFgColor = ui.ColorGreen
		infoWidget.TextBgColor = ui.ColorBlack
	}
	infoWidget.Border.Label = "INFO"
	// Machine List
	list := ui.NewList()
	list.Border.Label = "HOSTS"
	wf.widgets["machine"] = list
	// Machine Output
	outputWidget := ui.NewPar("0")
	outputWidget.Text = "INIT"
	outputWidget.Border.Label = "OUTPUT"
	wf.widgets["output"] = outputWidget
	// Hostlist
	digits := len(strconv.FormatInt(int64(count), 10))
	for index, host := range bf.hosts() {
		fmtStr := fmt.Sprintf("[%%%dd] %%s", digits)
		mPar := ui.NewPar(fmt.Sprintf(fmtStr, index+1, host))
		mPar.Height = 1
		mPar.Width = ui.TermWidth()/2 - 6
		mPar.HasBorder = false
		mPar.X = 5
		mPar.Y = 4 + index
		mPar.TextFgColor = ui.ColorBlue
		mPar.TextBgColor = ui.ColorWhite
		mPar.BgColor = ui.ColorYellow
		mPar.IsDisplay = false
		wf.machineWidets = append(wf.machineWidets, mPar)
		wf.machineOutput = append(wf.machineOutput, new(Output))
	}
	// Arrow
	arrow := ui.NewPar("->")
	arrow.Height = 1
	arrow.X = 2
	arrow.TextFgColor = ui.ColorCyan
	arrow.HasBorder = false
	wf.widgets["arrow"] = arrow
	ui.Body.AddRows(
		ui.NewRow(
			ui.NewCol(8, 0, gauge),
			ui.NewCol(4, 0, infoWidget),
		),
		ui.NewRow(
			ui.NewCol(6, 0, list),
			ui.NewCol(6, 6, outputWidget),
		),
		ui.NewRow(
			ui.NewCol(12, 0, helpWidget),
		),
	)
	wf.selectItem(0)
	go func() {
		for {
			wf.event <- tm.PollEvent()
		}
	}()
	go wf.run()
	return wf
}

// run starts UI.
func (wf *WindowFormatter) run() {
	for {
		select {
		case e := <-wf.event:
			if e.Type == tm.EventResize {
				wf.updateMain()
				wf.refresh()
			} else if e.Type == tm.EventKey {
				switch e.Ch {
				case 'q':
					wf.terminate()
					os.Exit(2)
				case 'j':
					wf.selectedIndex = (wf.selectedIndex + 1) % len(wf.machineWidets)
					wf.selectItem(wf.selectedIndex)
				case 'k':
					machineCount := len(wf.machineWidets)
					if wf.selectedIndex == 0 {
						wf.selectedIndex = machineCount - 1
					} else {
						wf.selectedIndex = (wf.selectedIndex - 1) % machineCount
					}
					wf.selectItem(wf.selectedIndex)
				}
			}
		}
	}
}

func (wf *WindowFormatter) terminate() {
	ui.Close()
}

func (wf *WindowFormatter) refresh() {
	ui.Body.Width = ui.TermWidth()
	ui.Body.Align()
	bufferers := []ui.Bufferer{ui.Body}
	ms := wf.machineSlice()
	for index, machine := range ms {
		machine.(*ui.Par).Y = index + wf.headerYShift
	}
	bufferers = append(bufferers, ms...)
	arrow := wf.widgets["arrow"]
	bufferers = append(bufferers, arrow)
	ui.Render(bufferers...)
}

func (wf *WindowFormatter) mainHeightCalc() int {
	helpWidget := wf.widgets["help"]
	progress := wf.widgets["progress"]
	mainHeight := ui.TermHeight() - helpWidget.GetHeight() - progress.GetHeight()
	return mainHeight
}

func (wf *WindowFormatter) updateMain() {
	list := wf.widgets["machine"].(*ui.List)
	outputWidget := wf.widgets["output"].(*ui.Par)
	mainHeight := wf.mainHeightCalc()
	list.Height = mainHeight
	if mainHeight > 2 {
		wf.pageSize = mainHeight - 2
	} else {
		wf.pageSize = 0
	}
	width := ui.TermWidth()/2 - 6
	for _, m := range wf.machineWidets {
		m.(*ui.Par).Width = width
	}
	outputWidget.Height = mainHeight
}

func (wf *WindowFormatter) machineSlice() []ui.Bufferer {
	start := wf.pageSize * wf.selectedPage
	end := start + wf.pageSize
	if end >= wf.machineCount {
		end = wf.machineCount
	}
	return wf.machineWidets[start:end]
}

func (wf *WindowFormatter) selectItem(index int) {
	wf.updateMain()
	arrow := wf.widgets["arrow"].(*ui.Par)
	if wf.pageSize > 0 {
		residue := index % wf.pageSize
		arrow.Y = residue + wf.headerYShift
		wf.selectedPage = index / wf.pageSize
	}
	outputWidget := wf.widgets["output"].(*ui.Par)
	output := wf.machineOutput[index]
	if output.Stdout != "" {
		outputWidget.Text = output.Stdout
		outputWidget.TextFgColor = ui.ColorWhite
		outputWidget.TextBgColor = ui.ColorBlack
	} else if output.Stderr != "" {
		outputWidget.Text = output.Stderr
		outputWidget.TextFgColor = ui.ColorRed
		outputWidget.TextBgColor = ui.ColorWhite
	} else if output.Error != "" {
		outputWidget.Text = output.Error
		outputWidget.TextFgColor = ui.ColorRed
		outputWidget.TextBgColor = ui.ColorWhite
	} else {
		outputWidget.Text = ""
	}
	wf.refresh()
}

// pragma mark - Formatter Interface

// Add refreshes contents on screen
func (wf *WindowFormatter) Add(output *Output) {
	wf.progress += wf.step
	gauge := wf.widgets["progress"].(*ui.Gauge)
	progressInt := int(wf.progress)
	if progressInt > 100 {
		progressInt = 100
	}
	gauge.Percent = progressInt
	index := output.Index
	machineWidget := wf.machineWidets[index].(*ui.Par)
	if output.ExitCode == 0 {
		machineWidget.TextFgColor = ui.ColorGreen
		machineWidget.TextBgColor = ui.ColorBlack
	} else {
		machineWidget.TextFgColor = ui.ColorRed
		machineWidget.TextBgColor = ui.ColorBlack
	}
	wf.machineOutput[index] = output
	wf.selectItem(wf.selectedIndex)
}

// Print waits a while and then close UI
func (wf *WindowFormatter) Print() {
	time.Sleep(5 * time.Second)
	wf.terminate()
}
<commit_msg>Window Formatter color adjust.<commit_after>package formatter

import (
	"fmt"
	ui "github.com/gizak/termui"
	tm "github.com/nsf/termbox-go"
	"os"
	"strconv"
	"time"
)

// WindowFormatter shows Outputs with termui
type WindowFormatter struct {
	widgets       map[string]ui.GridBufferer
	machineWidets []ui.Bufferer
	machineOutput []*Output
	machineCount  int
	headerYShift  int
	event         chan tm.Event
	list          []string
	progress      float64
	step          float64
	selectedIndex int
	pageSize      int
	selectedPage  int
	*abstractFormatter
}

// NewWindowFormatter initializes a WindowFormatter, and starts it.
func NewWindowFormatter() *WindowFormatter {
	bf := newAbstractFormatter()
	count := len(bf.hosts())
	wf := &WindowFormatter{
		widgets:       make(map[string]ui.GridBufferer),
		machineWidets: make([]ui.Bufferer, 0, count),
		machineOutput: make([]*Output, 0, count),
		machineCount:  count,
		event:         make(chan tm.Event),
		list:          make([]string, 0, count),
		progress:      0,
		step:          100 / float64(count),
		selectedIndex: 0,
		selectedPage:  0,
	}
	wf.abstractFormatter = bf
	err := ui.Init()
	if err != nil {
		panic(err)
	}
	ui.UseTheme("helloworld")

	// Footer
	// help Box
	helpWidget := ui.NewPar("q:QUIT; j:DOWN; k:UP")
	helpWidget.Height = 3
	helpWidget.Border.Label = "HELP"
	helpWidget.Border.FgColor = ui.ColorCyan
	helpWidget.TextFgColor = ui.ColorWhite
	wf.widgets["help"] = helpWidget
	// Header
	// progess Gauge
	headerHeight := 3
	gauge := ui.NewGauge()
	gauge.Height = headerHeight
	gauge.Percent = 0
	gauge.Border.Label = "PROGRESS"
	gauge.Border.FgColor = ui.ColorCyan
	gauge.BarColor = ui.ColorGreen
	wf.widgets["progress"] = gauge
	wf.headerYShift = gauge.Height + 1
	// info Textbox
	infoText := fmt.Sprintf("USER : %s", info.User)
	infoWidget := ui.NewPar(infoText)
	infoWidget.Height = headerHeight
	if info.User == "root" {
		infoWidget.Border.FgColor = ui.ColorRed
		infoWidget.TextFgColor = ui.ColorRed
		infoWidget.Border.LabelFgColor = ui.ColorRed
	} else {
		infoWidget.Border.FgColor = ui.ColorCyan
		infoWidget.TextFgColor = ui.ColorGreen
		infoWidget.TextBgColor = ui.ColorBlack
	}
	infoWidget.Border.Label = "INFO"
	// Machine List
	list := ui.NewList()
	list.Border.Label = "HOSTS"
	wf.widgets["machine"] = list
	// Machine Output
	outputWidget := ui.NewPar("0")
	outputWidget.Text = "INIT"
	outputWidget.Border.Label = "OUTPUT"
	wf.widgets["output"] = outputWidget
	// Hostlist
	digits := len(strconv.FormatInt(int64(count), 10))
	for index, host := range bf.hosts() {
		fmtStr := fmt.Sprintf("[%%%dd] %%s", digits)
		mPar := ui.NewPar(fmt.Sprintf(fmtStr, index+1, host))
		mPar.Height = 1
		mPar.Width = ui.TermWidth()/2 - 6
		mPar.HasBorder = false
		mPar.X = 5
		mPar.Y = 4 + index
		mPar.TextFgColor = ui.ColorBlue
		mPar.TextBgColor = ui.ColorWhite
		mPar.BgColor = ui.ColorYellow
		mPar.IsDisplay = false
		wf.machineWidets = append(wf.machineWidets, mPar)
		wf.machineOutput = append(wf.machineOutput, new(Output))
	}
	// Arrow
	arrow := ui.NewPar("->")
	arrow.Height = 1
	arrow.X = 2
	arrow.TextFgColor = ui.ColorCyan
	arrow.HasBorder = false
	wf.widgets["arrow"] = arrow
	ui.Body.AddRows(
		ui.NewRow(
			ui.NewCol(8, 0, gauge),
			ui.NewCol(4, 0, infoWidget),
		),
		ui.NewRow(
			ui.NewCol(6, 0, list),
			ui.NewCol(6, 6, outputWidget),
		),
		ui.NewRow(
			ui.NewCol(12, 0, helpWidget),
		),
	)
	wf.selectItem(0)
	go func() {
		for {
			wf.event <- tm.PollEvent()
		}
	}()
	go wf.run()
	return wf
}

// run starts UI.
func (wf *WindowFormatter) run() {
	for {
		select {
		case e := <-wf.event:
			if e.Type == tm.EventResize {
				wf.updateMain()
				wf.refresh()
			} else if e.Type == tm.EventKey {
				switch e.Ch {
				case 'q':
					wf.terminate()
					os.Exit(2)
				case 'j':
					wf.selectedIndex = (wf.selectedIndex + 1) % len(wf.machineWidets)
					wf.selectItem(wf.selectedIndex)
				case 'k':
					machineCount := len(wf.machineWidets)
					if wf.selectedIndex == 0 {
						wf.selectedIndex = machineCount - 1
					} else {
						wf.selectedIndex = (wf.selectedIndex - 1) % machineCount
					}
					wf.selectItem(wf.selectedIndex)
				}
			}
		}
	}
}

func (wf *WindowFormatter) terminate() {
	ui.Close()
}

func (wf *WindowFormatter) refresh() {
	ui.Body.Width = ui.TermWidth()
	ui.Body.Align()
	bufferers := []ui.Bufferer{ui.Body}
	ms := wf.machineSlice()
	for index, machine := range ms {
		machine.(*ui.Par).Y = index + wf.headerYShift
	}
	bufferers = append(bufferers, ms...)
	arrow := wf.widgets["arrow"]
	bufferers = append(bufferers, arrow)
	ui.Render(bufferers...)
}

func (wf *WindowFormatter) mainHeightCalc() int {
	helpWidget := wf.widgets["help"]
	progress := wf.widgets["progress"]
	mainHeight := ui.TermHeight() - helpWidget.GetHeight() - progress.GetHeight()
	return mainHeight
}

func (wf *WindowFormatter) updateMain() {
	list := wf.widgets["machine"].(*ui.List)
	outputWidget := wf.widgets["output"].(*ui.Par)
	mainHeight := wf.mainHeightCalc()
	list.Height = mainHeight
	if mainHeight > 2 {
		wf.pageSize = mainHeight - 2
	} else {
		wf.pageSize = 0
	}
	width := ui.TermWidth()/2 - 6
	for _, m := range wf.machineWidets {
		m.(*ui.Par).Width = width
	}
	outputWidget.Height = mainHeight
}

func (wf *WindowFormatter) machineSlice() []ui.Bufferer {
	start := wf.pageSize * wf.selectedPage
	end := start + wf.pageSize
	if end >= wf.machineCount {
		end = wf.machineCount
	}
	return wf.machineWidets[start:end]
}

func (wf *WindowFormatter) selectItem(index int) {
	wf.updateMain()
	arrow := wf.widgets["arrow"].(*ui.Par)
	if wf.pageSize > 0 {
		residue := index % wf.pageSize
		arrow.Y = residue + wf.headerYShift
		wf.selectedPage = index / wf.pageSize
	}
	outputWidget := wf.widgets["output"].(*ui.Par)
	output := wf.machineOutput[index]
	if output.Stdout != "" {
		outputWidget.Text = output.Stdout
		outputWidget.TextFgColor = ui.ColorWhite
		outputWidget.TextBgColor = ui.ColorBlack
	} else if output.Stderr != "" {
		outputWidget.Text = output.Stderr
		outputWidget.TextFgColor = ui.ColorRed
		outputWidget.TextBgColor = ui.ColorWhite
	} else if output.Error != "" {
		outputWidget.Text = output.Error
		outputWidget.TextFgColor = ui.ColorRed
		outputWidget.TextBgColor = ui.ColorWhite
	} else {
		outputWidget.Text = ""
	}
	wf.refresh()
}

// pragma mark - Formatter Interface

// Add refreshes contents on screen
func (wf *WindowFormatter) Add(output *Output) {
	wf.progress += wf.step
	gauge := wf.widgets["progress"].(*ui.Gauge)
	progressInt := int(wf.progress)
	if progressInt > 100 {
		progressInt = 100
	}
	gauge.Percent = progressInt
	index := output.Index
	machineWidget := wf.machineWidets[index].(*ui.Par)
	if output.ExitCode == 0 {
		machineWidget.TextFgColor = ui.ColorGreen
		machineWidget.TextBgColor = ui.ColorBlack
	} else {
		machineWidget.TextFgColor = ui.ColorRed
		machineWidget.TextBgColor = ui.ColorBlack
	}
	wf.machineOutput[index] = output
	wf.selectItem(wf.selectedIndex)
}

// Print waits a while and then close UI
func (wf *WindowFormatter) Print() {
	time.Sleep(5 * time.Second)
	wf.terminate()
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"sync"
	"time"

	"github.com/gorilla/context"
	"github.com/gorilla/mux"
	"github.com/oleksandr/bonjour"
)

const serviceName = "animation_server"

func main() {
	flag.Parse()
	if !*server && !*client {
		log.Println("must run either in server or client mode")
		os.Exit(1)
	}
	if *server && *client {
		log.Println("cannot run both in server and client mode")
		os.Exit(1)
	}
	s := &service{}
	if *server {
		log.Println("running server on port", *port)
		if len(*folder) == 0 {
			log.Println("must specify folder")
			os.Exit(1)
		}
		isThere, err := exists(*folder)
		if err != nil {
			log.Println(err)
			os.Exit(1)
		}
		if !isThere {
			log.Println("folder", *folder, "does not exist")
			os.Exit(1)
		}
		if err := s.register(); err != nil {
			log.Println(err)
			os.Exit(1)
		}
	}
	if *client {
		log.Println("running client on port", *port)
		go func() {
			if err := s.browseUpdates(); err != nil {
				log.Println(err)
				os.Exit(1)
			}
		}()
		if err := s.proxyRequests(); err != nil {
			log.Println(err)
			os.Exit(1)
		}
	}
	os.Exit(0)
}

func (s *service) handlerFunc(w http.ResponseWriter, r *http.Request) {
	resp, err := http.Get(fmt.Sprintf("http://%s:%d/gamestats.json", s.HostName, s.Port))
	if err != nil {
		log.Println(err)
		http.Error(w, err.Error(), 500)
		return
	}
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Println(err)
		http.Error(w, err.Error(), 500)
		return
	}
	w.Header().Add("Access-Control-Allow-Origin", "*")
	w.Header().Add("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With")
	w.Header().Add("Access-Control-Allow-Methods", "GET, OPTIONS, PUT, POST, DELETE")
	w.Header().Add("Access-Control-Allow-Credentials", "true")
	w.Header().Set("Content-Type", "application/json")
	defer resp.Body.Close()
	_, err = w.Write(b)
	if err != nil {
		log.Println(err)
	}
}

func (s *service) proxyRequests() error {
	router := mux.NewRouter()
	router.HandleFunc("/gamestats.json", s.handlerFunc).Methods("GET", "OPTIONS")
	return http.ListenAndServe(fmt.Sprintf(":%d", *port), context.ClearHandler(router))
}

// exists returns whether the given file or directory exists or not
func exists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return true, err
}

var (
	server = flag.Bool("server", false, "serve data file over HTTP and advertise the service")
	folder = flag.String("folder", ".", "folder that includes gamestats.json")
	client = flag.Bool("client", false, "find where HTTP data is served and proxy it to localhost")
	port   = flag.Int("port", 8000, "port to listen on")
)

type service struct {
	HostName string
	Port     int
	m        sync.Mutex
}

func (s *service) update(entry *bonjour.ServiceEntry) {
	s.m.Lock()
	defer s.m.Unlock()
	s.HostName = entry.HostName
	s.Port = entry.Port
}

func (s *service) String() string {
	return fmt.Sprintf("%s:%d", s.HostName, s.Port)
}

func (s *service) register() error {
	// Run registration (blocking call)
	bonjourService, err := bonjour.Register(serviceName, "_foobar._tcp", "", *port, []string{"txtv=1", "app=test"}, nil)
	if err != nil {
		return err
	}
	defer bonjourService.Shutdown()
	h := http.FileServer(http.Dir(*folder))
	return http.ListenAndServe(fmt.Sprintf(":%d", *port), h)
}

func (s *service) browseUpdates() error {
	log.Println("resolving")

	resolver, err := bonjour.NewResolver(nil)
	if err != nil {
		log.Println("Failed to initialize resolver:", err.Error())
		return err
	}

	results := make(chan *bonjour.ServiceEntry)

	go func(results chan *bonjour.ServiceEntry, exitCh chan<- bool) {
		for e := range results {
			log.Printf("found service %s", e.Instance)
			if serviceName == e.Instance {
				s.update(e)
				log.Println("updated", s)
			}
		}
	}(results, resolver.Exit)

	go func() {
		for {
			err := resolver.Browse("_foobar._tcp", "local.", results)
			if err != nil {
				log.Println("Failed to browse:", err.Error())
			}
			time.Sleep(1 * time.Second)
		}
	}()

	select {}
}
<commit_msg>dont error out if backend fetch fails<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"sync"
	"time"

	"github.com/gorilla/context"
	"github.com/gorilla/mux"
	"github.com/oleksandr/bonjour"
)

const serviceName = "animation_server"

func main() {
	flag.Parse()
	if !*server && !*client {
		log.Println("must run either in server or client mode")
		os.Exit(1)
	}
	if *server && *client {
		log.Println("cannot run both in server and client mode")
		os.Exit(1)
	}
	s := &service{}
	if *server {
		log.Println("running server on port", *port)
		if len(*folder) == 0 {
			log.Println("must specify folder")
			os.Exit(1)
		}
		isThere, err := exists(*folder)
		if err != nil {
			log.Println(err)
			os.Exit(1)
		}
		if !isThere {
			log.Println("folder", *folder, "does not exist")
			os.Exit(1)
		}
		if err := s.register(); err != nil {
			log.Println(err)
			os.Exit(1)
		}
	}
	if *client {
		log.Println("running client on port", *port)
		go func() {
			if err := s.browseUpdates(); err != nil {
				log.Println(err)
				os.Exit(1)
			}
		}()
		if err := s.proxyRequests(); err != nil {
			log.Println(err)
			os.Exit(1)
		}
	}
	os.Exit(0)
}

func (s *service) fetchData() ([]byte, error) {
	resp, err := http.Get(fmt.Sprintf("http://%s:%d/gamestats.json", s.HostName, s.Port))
	if err != nil {
		return nil, err
	}
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	return b, nil
}

func (s *service) handlerFunc(w http.ResponseWriter, r *http.Request) {
	b, err := s.fetchData()
	if err != nil {
		log.Println(err)
	}
	w.Header().Add("Access-Control-Allow-Origin", "*")
	w.Header().Add("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With")
	w.Header().Add("Access-Control-Allow-Methods", "GET, OPTIONS, PUT, POST, DELETE")
	w.Header().Add("Access-Control-Allow-Credentials", "true")
	w.Header().Set("Content-Type", "application/json")
	_, err = w.Write(b)
	if err != nil {
		log.Println(err)
	}
}

func (s *service) proxyRequests() error {
	router := mux.NewRouter()
	router.HandleFunc("/gamestats.json", s.handlerFunc).Methods("GET", "OPTIONS")
	return http.ListenAndServe(fmt.Sprintf(":%d", *port), context.ClearHandler(router))
}

// exists returns whether the given file or directory exists or not
func exists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return true, err
}

var (
	server = flag.Bool("server", false, "serve data file over HTTP and advertise the service")
	folder = flag.String("folder", ".", "folder that includes gamestats.json")
	client = flag.Bool("client", false, "find where HTTP data is served and proxy it to localhost")
	port   = flag.Int("port", 8000, "port to listen on")
)

type service struct {
	HostName string
	Port     int
	m        sync.Mutex
}

func (s *service) update(entry *bonjour.ServiceEntry) {
	s.m.Lock()
	defer s.m.Unlock()
	s.HostName = entry.HostName
	s.Port = entry.Port
}

func (s *service) String() string {
	return fmt.Sprintf("%s:%d", s.HostName, s.Port)
}

func (s *service) register() error {
	// Run registration (blocking call)
	bonjourService, err := bonjour.Register(serviceName, "_foobar._tcp", "", *port, []string{"txtv=1", "app=test"}, nil)
	if err != nil {
		return err
	}
	defer bonjourService.Shutdown()
	h := http.FileServer(http.Dir(*folder))
	return http.ListenAndServe(fmt.Sprintf(":%d", *port), h)
}

func (s *service) browseUpdates() error {
	log.Println("resolving")

	resolver, err := bonjour.NewResolver(nil)
	if err != nil {
		log.Println("Failed to initialize resolver:", err.Error())
		return err
	}

	results := make(chan *bonjour.ServiceEntry)

	go func(results chan *bonjour.ServiceEntry, exitCh chan<- bool) {
		for e := range results {
			log.Printf("found service %s", e.Instance)
			if serviceName == e.Instance {
				s.update(e)
				log.Println("updated", s)
			}
		}
	}(results, resolver.Exit)

	go func() {
		for {
			err := resolver.Browse("_foobar._tcp", "local.", results)
			if err != nil {
				log.Println("Failed to browse:", err.Error())
			}
			time.Sleep(1 * time.Second)
		}
	}()

	select {}
}
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package inode

import (
	"os"
	"sync"

	"github.com/jacobsa/fuse/fuseops"
	"github.com/jacobsa/gcloud/gcs"
	"golang.org/x/net/context"
)

// When this custom metadata key is present in an object record, it is to be
// treated as a symlink. For use in testing only; other users should detect
// this with IsSymlink.
const SymlinkMetadataKey = "gcsfuse_symlink_target"

// Does the supplied object represent a symlink inode?
func IsSymlink(o *gcs.Object) bool {
	_, ok := o.Metadata[SymlinkMetadataKey]
	return ok
}

type SymlinkInode struct {
	/////////////////////////
	// Constant data
	/////////////////////////

	id               fuseops.InodeID
	name             string
	sourceGeneration int64
	attrs            fuseops.InodeAttributes
	target           string

	/////////////////////////
	// Mutable state
	/////////////////////////

	mu sync.Mutex

	// GUARDED_BY(mu)
	lc lookupCount
}

var _ Inode = &SymlinkInode{}

// Create a symlink inode for the supplied object record.
//
// REQUIRES: IsSymlink(o)
func NewSymlinkInode(
	id fuseops.InodeID,
	o *gcs.Object,
	uid uint32,
	gid uint32,
	permissions os.FileMode) (s *SymlinkInode) {
	// Create the inode.
	s = &SymlinkInode{
		id:               id,
		name:             o.Name,
		sourceGeneration: o.Generation,
		attrs: fuseops.InodeAttributes{
			Nlink: 1,
			Uid:   uid,
			Gid:   gid,
			Mode:  permissions | os.ModeSymlink,
			Mtime: o.Updated,
		},
		target: o.Metadata[SymlinkMetadataKey],
	}

	// Set up lookup counting.
	s.lc.Init(id)

	return
}

////////////////////////////////////////////////////////////////////////
// Public interface
////////////////////////////////////////////////////////////////////////

func (s *SymlinkInode) Lock() {
	s.mu.Lock()
}

func (s *SymlinkInode) Unlock() {
	s.mu.Unlock()
}

func (s *SymlinkInode) ID() fuseops.InodeID {
	return s.id
}

func (s *SymlinkInode) Name() string {
	return s.name
}

// Return the object generation number from which this inode was branched.
//
// Does not require the lock to be held.
func (s *SymlinkInode) SourceGeneration() int64 {
	return s.sourceGeneration
}

// LOCKS_REQUIRED(s.mu)
func (s *SymlinkInode) IncrementLookupCount() {
	s.lc.Inc()
}

// LOCKS_REQUIRED(s.mu)
func (s *SymlinkInode) DecrementLookupCount(n uint64) (destroy bool) {
	destroy = s.lc.Dec(n)
	return
}

// LOCKS_REQUIRED(s.mu)
func (s *SymlinkInode) Destroy() (err error) {
	// Nothing to do.
	return
}

func (s *SymlinkInode) Attributes(
	ctx context.Context) (attrs fuseops.InodeAttributes, err error) {
	attrs = s.attrs
	return
}

// Return the target of the symlink.
func (s *SymlinkInode) Target() (target string) {
	target = s.target
	return
}
<commit_msg>Accept attributes in NewSymlinkInode.<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package inode

import (
	"sync"

	"github.com/jacobsa/fuse/fuseops"
	"github.com/jacobsa/gcloud/gcs"
	"golang.org/x/net/context"
)

// When this custom metadata key is present in an object record, it is to be
// treated as a symlink. For use in testing only; other users should detect
// this with IsSymlink.
const SymlinkMetadataKey = "gcsfuse_symlink_target"

// Does the supplied object represent a symlink inode?
func IsSymlink(o *gcs.Object) bool {
	_, ok := o.Metadata[SymlinkMetadataKey]
	return ok
}

type SymlinkInode struct {
	/////////////////////////
	// Constant data
	/////////////////////////

	id               fuseops.InodeID
	name             string
	sourceGeneration int64
	attrs            fuseops.InodeAttributes
	target           string

	/////////////////////////
	// Mutable state
	/////////////////////////

	mu sync.Mutex

	// GUARDED_BY(mu)
	lc lookupCount
}

var _ Inode = &SymlinkInode{}

// Create a symlink inode for the supplied object record.
//
// REQUIRES: IsSymlink(o)
func NewSymlinkInode(
	id fuseops.InodeID,
	o *gcs.Object,
	attrs fuseops.InodeAttributes) (s *SymlinkInode) {
	// Create the inode.
	s = &SymlinkInode{
		id:               id,
		name:             o.Name,
		sourceGeneration: o.Generation,
		attrs: fuseops.InodeAttributes{
			Nlink: 1,
			Uid:   attrs.Uid,
			Gid:   attrs.Gid,
			Mode:  attrs.Mode,
			Mtime: o.Updated,
		},
		target: o.Metadata[SymlinkMetadataKey],
	}

	// Set up lookup counting.
	s.lc.Init(id)

	return
}

////////////////////////////////////////////////////////////////////////
// Public interface
////////////////////////////////////////////////////////////////////////

func (s *SymlinkInode) Lock() {
	s.mu.Lock()
}

func (s *SymlinkInode) Unlock() {
	s.mu.Unlock()
}

func (s *SymlinkInode) ID() fuseops.InodeID {
	return s.id
}

func (s *SymlinkInode) Name() string {
	return s.name
}

// Return the object generation number from which this inode was branched.
//
// Does not require the lock to be held.
func (s *SymlinkInode) SourceGeneration() int64 {
	return s.sourceGeneration
}

// LOCKS_REQUIRED(s.mu)
func (s *SymlinkInode) IncrementLookupCount() {
	s.lc.Inc()
}

// LOCKS_REQUIRED(s.mu)
func (s *SymlinkInode) DecrementLookupCount(n uint64) (destroy bool) {
	destroy = s.lc.Dec(n)
	return
}

// LOCKS_REQUIRED(s.mu)
func (s *SymlinkInode) Destroy() (err error) {
	// Nothing to do.
	return
}

func (s *SymlinkInode) Attributes(
	ctx context.Context) (attrs fuseops.InodeAttributes, err error) {
	attrs = s.attrs
	return
}

// Return the target of the symlink.
func (s *SymlinkInode) Target() (target string) {
	target = s.target
	return
}
<|endoftext|>


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

// Package bits implements bit counting and manipulation
// functions for the predeclared unsigned integer types.
package bits

// UintSize is the size of a uint in bits.
const UintSize = uintSize

// --- LeadingZeros ---

// LeadingZeros returns the number of leading zero bits in x; the result is UintSize for x == 0.
func LeadingZeros(x uint) int { return UintSize - blen(uint64(x)) }

// LeadingZeros8 returns the number of leading zero bits in x; the result is 8 for x == 0.
func LeadingZeros8(x uint8) int { return 8 - blen(uint64(x)) }

// LeadingZeros16 returns the number of leading zero bits in x; the result is 16 for x == 0.
func LeadingZeros16(x uint16) int { return 16 - blen(uint64(x)) }

// LeadingZeros32 returns the number of leading zero bits in x; the result is 32 for x == 0.
func LeadingZeros32(x uint32) int { return 32 - blen(uint64(x)) }

// LeadingZeros64 returns the number of leading zero bits in x; the result is 64 for x == 0.
func LeadingZeros64(x uint64) int { return 64 - blen(uint64(x)) }

// --- TrailingZeros ---

// TrailingZeros returns the number of trailing zero bits in x; the result is 0 for x == 0.
func TrailingZeros(x uint) int { return ntz(x) }

// TrailingZeros8 returns the number of trailing zero bits in x; the result is 0 for x == 0.
func TrailingZeros8(x uint8) int { return ntz8(x) }

// TrailingZeros16 returns the number of trailing zero bits in x; the result is 0 for x == 0.
func TrailingZeros16(x uint16) int { return ntz16(x) }

// TrailingZeros32 returns the number of trailing zero bits in x; the result is 0 for x == 0.
func TrailingZeros32(x uint32) int { return ntz32(x) }

// TrailingZeros64 returns the number of trailing zero bits in x; the result is 0 for x == 0.
func TrailingZeros64(x uint64) int { return ntz64(x) }

// --- OnesCount ---

const m0 = 0x5555555555555555 // 01010101 ...
const m1 = 0x3333333333333333 // 00110011 ...
const m2 = 0x0f0f0f0f0f0f0f0f // 00001111 ...
const m3 = 0x00ff00ff00ff00ff // etc.
const m4 = 0x0000ffff0000ffff

// OnesCount returns the number of one bits ("population count") in x.
func OnesCount(x uint) int {
	if UintSize == 32 {
		return OnesCount32(uint32(x))
	}
	return OnesCount64(uint64(x))
}

// OnesCount8 returns the number of one bits ("population count") in x.
func OnesCount8(x uint8) int {
	const m = 1<<8 - 1
	x = x>>1&(m0&m) + x&(m0&m)
	x = x>>2&(m1&m) + x&(m1&m)
	x += x >> 4
	return int(x) & (1<<4 - 1)
}

// OnesCount16 returns the number of one bits ("population count") in x.
func OnesCount16(x uint16) int {
	const m = 1<<16 - 1
	x = x>>1&(m0&m) + x&(m0&m)
	x = x>>2&(m1&m) + x&(m1&m)
	x = (x>>4 + x) & (m2 & m)
	x += x >> 8
	return int(x) & (1<<5 - 1)
}

// OnesCount32 returns the number of one bits ("population count") in x.
func OnesCount32(x uint32) int {
	const m = 1<<32 - 1
	x = x>>1&(m0&m) + x&(m0&m)
	x = x>>2&(m1&m) + x&(m1&m)
	x = (x>>4 + x) & (m2 & m)
	x += x >> 8
	x += x >> 16
	return int(x) & (1<<6 - 1)
}

// OnesCount64 returns the number of one bits ("population count") in x.
func OnesCount64(x uint64) int {
	// Implementation: Parallel summing of adjacent bits.
	// See "Hacker's Delight", Chap. 5: Counting Bits.
	// The following pattern shows the general approach:
	//
	//   x = x>>1&(m0&m) + x&(m0&m)
	//   x = x>>2&(m1&m) + x&(m1&m)
	//   x = x>>4&(m2&m) + x&(m2&m)
	//   x = x>>8&(m3&m) + x&(m3&m)
	//   x = x>>16&(m4&m) + x&(m4&m)
	//   x = x>>32&(m5&m) + x&(m5&m)
	//   return int(x)
	//
	// Masking (& operations) can be left away when there's no
	// danger that a field's sum will carry over into the next
	// field: Since the result cannot be > 64, 8 bits is enough
	// and we can ignore the masks for the shifts by 8 and up.
	// Per "Hacker's Delight", the first line can be simplified
	// more, but it saves at best one instruction, so we leave
	// it alone for clarity.
	const m = 1<<64 - 1
	x = x>>1&(m0&m) + x&(m0&m)
	x = x>>2&(m1&m) + x&(m1&m)
	x = (x>>4 + x) & (m2 & m)
	x += x >> 8
	x += x >> 16
	x += x >> 32
	return int(x) & (1<<7 - 1)
}

// --- RotateLeft ---

// RotateLeft returns the value of x rotated left by k bits; k must not be negative.
func RotateLeft(x uint, k int) uint {
	if UintSize == 32 {
		return uint(RotateLeft32(uint32(x), k))
	}
	return uint(RotateLeft64(uint64(x), k))
}

// RotateLeft8 returns the value of x rotated left by k bits; k must not be negative.
func RotateLeft8(x uint8, k int) uint8 {
	if k < 0 {
		panic("negative rotation count")
	}
	const n = 8
	s := uint(k) & (n - 1)
	return x<<s | x>>(n-s)
}

// RotateLeft16 returns the value of x rotated left by k bits; k must not be negative.
func RotateLeft16(x uint16, k int) uint16 {
	if k < 0 {
		panic("negative rotation count")
	}
	const n = 16
	s := uint(k) & (n - 1)
	return x<<s | x>>(n-s)
}

// RotateLeft32 returns the value of x rotated left by k bits; k must not be negative.
func RotateLeft32(x uint32, k int) uint32 {
	if k < 0 {
		panic("negative rotation count")
	}
	const n = 32
	s := uint(k) & (n - 1)
	return x<<s | x>>(n-s)
}

// RotateLeft64 returns the value of x rotated left by k bits; k must not be negative.
func RotateLeft64(x uint64, k int) uint64 {
	if k < 0 {
		panic("negative rotation count")
	}
	const n = 64
	s := uint(k) & (n - 1)
	return x<<s | x>>(n-s)
}

// --- RotateRight ---

// RotateRight returns the value of x rotated left by k bits; k must not be negative.
func RotateRight(x uint, k int) uint {
	if UintSize == 32 {
		return uint(RotateRight32(uint32(x), k))
	}
	return uint(RotateRight64(uint64(x), k))
}

// RotateRight8 returns the value of x rotated left by k bits; k must not be negative.
func RotateRight8(x uint8, k int) uint8 {
	if k < 0 {
		panic("negative rotation count")
	}
	const n = 8
	s := uint(k) & (n - 1)
	return x<<(n-s) | x>>s
}

// RotateRight16 returns the value of x rotated left by k bits; k must not be negative.
func RotateRight16(x uint16, k int) uint16 {
	if k < 0 {
		panic("negative rotation count")
	}
	const n = 16
	s := uint(k) & (n - 1)
	return x<<(n-s) | x>>s
}

// RotateRight32 returns the value of x rotated left by k bits; k must not be negative.
func RotateRight32(x uint32, k int) uint32 {
	if k < 0 {
		panic("negative rotation count")
	}
	const n = 32
	s := uint(k) & (n - 1)
	return x<<(n-s) | x>>s
}

// RotateRight64 returns the value of x rotated left by k bits; k must not be negative.
func RotateRight64(x uint64, k int) uint64 {
	if k < 0 {
		panic("negative rotation count")
	}
	const n = 64
	s := uint(k) & (n - 1)
	return x<<(n-s) | x>>s
}

// --- Reverse ---

// Reverse returns the value of x with its bits in reversed order.
func Reverse(x uint) uint {
	if UintSize == 32 {
		return uint(Reverse32(uint32(x)))
	}
	return uint(Reverse64(uint64(x)))
}

// Reverse8 returns the value of x with its bits in reversed order.
func Reverse8(x uint8) uint8 {
	const m = 1<<8 - 1
	x = x>>1&(m0&m) | x&(m0&m)<<1
	x = x>>2&(m1&m) | x&(m1&m)<<2
	return x>>4 | x<<4
}

// Reverse16 returns the value of x with its bits in reversed order.
func Reverse16(x uint16) uint16 {
	const m = 1<<16 - 1
	x = x>>1&(m0&m) | x&(m0&m)<<1
	x = x>>2&(m1&m) | x&(m1&m)<<2
	x = x>>4&(m2&m) | x&(m2&m)<<4
	return x>>8 | x<<8
}

// Reverse32 returns the value of x with its bits in reversed order.
func Reverse32(x uint32) uint32 {
	const m = 1<<32 - 1
	x = x>>1&(m0&m) | x&(m0&m)<<1
	x = x>>2&(m1&m) | x&(m1&m)<<2
	x = x>>4&(m2&m) | x&(m2&m)<<4
	x = x>>8&(m3&m) | x&(m3&m)<<8
	return x>>16 | x<<16
}

// Reverse64 returns the value of x with its bits in reversed order.
func Reverse64(x uint64) uint64 {
	const m = 1<<64 - 1
	x = x>>1&(m0&m) | x&(m0&m)<<1
	x = x>>2&(m1&m) | x&(m1&m)<<2
	x = x>>4&(m2&m) | x&(m2&m)<<4
	x = x>>8&(m3&m) | x&(m3&m)<<8
	x = x>>16&(m4&m) | x&(m4&m)<<16
	return x>>32 | x<<32
}

// --- ReverseBytes ---

// ReverseBytes returns the value of x with its bytes in reversed order.
func ReverseBytes(x uint) uint {
	if UintSize == 32 {
		return uint(ReverseBytes32(uint32(x)))
	}
	return uint(ReverseBytes64(uint64(x)))
}

// ReverseBytes16 returns the value of x with its bytes in reversed order.
func ReverseBytes16(x uint16) uint16 {
	return x>>8 | x<<8
}

// ReverseBytes32 returns the value of x with its bytes in reversed order.
func ReverseBytes32(x uint32) uint32 {
	const m = 1<<32 - 1
	x = x>>8&(m3&m) | x&(m3&m)<<8
	return x>>16 | x<<16
}

// ReverseBytes64 returns the value of x with its bytes in reversed order.
func ReverseBytes64(x uint64) uint64 {
	const m = 1<<64 - 1
	x = x>>8&(m3&m) | x&(m3&m)<<8
	x = x>>16&(m4&m) | x&(m4&m)<<16
	return x>>32 | x<<32
}

// --- Len ---

// Len returns the minimum number of bits required to represent x; the result is 0 for x == 0.
func Len(x uint) int { return blen(uint64(x)) }

// Len8 returns the minimum number of bits required to represent x; the result is 0 for x == 0.
func Len8(x uint8) int { return blen(uint64(x)) }

// Len16 returns the minimum number of bits required to represent x; the result is 0 for x == 0.
func Len16(x uint16) int { return blen(uint64(x)) }

// Len32 returns the minimum number of bits required to represent x; the result is 0 for x == 0.
func Len32(x uint32) int { return blen(uint64(x)) }

// Len64 returns the minimum number of bits required to represent x; the result is 0 for x == 0.
func Len64(x uint64) int { return blen(uint64(x)) }
<commit_msg>math/bits: fix incorrect doc strings for TrailingZeros functions<commit_after>// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package bits implements bit counting and manipulation
// functions for the predeclared unsigned integer types.
package bits

// UintSize is the size of a uint in bits.
const UintSize = uintSize

// --- LeadingZeros ---

// LeadingZeros returns the number of leading zero bits in x; the result is UintSize for x == 0.
func LeadingZeros(x uint) int { return UintSize - blen(uint64(x)) }

// LeadingZeros8 returns the number of leading zero bits in x; the result is 8 for x == 0.
func LeadingZeros8(x uint8) int { return 8 - blen(uint64(x)) }

// LeadingZeros16 returns the number of leading zero bits in x; the result is 16 for x == 0.
func LeadingZeros16(x uint16) int { return 16 - blen(uint64(x)) }

// LeadingZeros32 returns the number of leading zero bits in x; the result is 32 for x == 0.
func LeadingZeros32(x uint32) int { return 32 - blen(uint64(x)) }

// LeadingZeros64 returns the number of leading zero bits in x; the result is 64 for x == 0.
func LeadingZeros64(x uint64) int { return 64 - blen(uint64(x)) }

// --- TrailingZeros ---

// TrailingZeros returns the number of trailing zero bits in x; the result is UintSize for x == 0.
func TrailingZeros(x uint) int { return ntz(x) }

// TrailingZeros8 returns the number of trailing zero bits in x; the result is 8 for x == 0.
func TrailingZeros8(x uint8) int { return ntz8(x) }

// TrailingZeros16 returns the number of trailing zero bits in x; the result is 16 for x == 0.
func TrailingZeros16(x uint16) int { return ntz16(x) }

// TrailingZeros32 returns the number of trailing zero bits in x; the result is 32 for x == 0.
func TrailingZeros32(x uint32) int { return ntz32(x) }

// TrailingZeros64 returns the number of trailing zero bits in x; the result is 64 for x == 0.
func TrailingZeros64(x uint64) int { return ntz64(x) }

// --- OnesCount ---

const m0 = 0x5555555555555555 // 01010101 ...
const m1 = 0x3333333333333333 // 00110011 ...
const m2 = 0x0f0f0f0f0f0f0f0f // 00001111 ...
const m3 = 0x00ff00ff00ff00ff // etc.
const m4 = 0x0000ffff0000ffff

// OnesCount returns the number of one bits ("population count") in x.
func OnesCount(x uint) int {
	if UintSize == 32 {
		return OnesCount32(uint32(x))
	}
	return OnesCount64(uint64(x))
}

// OnesCount8 returns the number of one bits ("population count") in x.
func OnesCount8(x uint8) int {
	const m = 1<<8 - 1
	x = x>>1&(m0&m) + x&(m0&m)
	x = x>>2&(m1&m) + x&(m1&m)
	x += x >> 4
	return int(x) & (1<<4 - 1)
}

// OnesCount16 returns the number of one bits ("population count") in x.
func OnesCount16(x uint16) int {
	const m = 1<<16 - 1
	x = x>>1&(m0&m) + x&(m0&m)
	x = x>>2&(m1&m) + x&(m1&m)
	x = (x>>4 + x) & (m2 & m)
	x += x >> 8
	return int(x) & (1<<5 - 1)
}

// OnesCount32 returns the number of one bits ("population count") in x.
func OnesCount32(x uint32) int {
	const m = 1<<32 - 1
	x = x>>1&(m0&m) + x&(m0&m)
	x = x>>2&(m1&m) + x&(m1&m)
	x = (x>>4 + x) & (m2 & m)
	x += x >> 8
	x += x >> 16
	return int(x) & (1<<6 - 1)
}

// OnesCount64 returns the number of one bits ("population count") in x.
func OnesCount64(x uint64) int {
	// Implementation: Parallel summing of adjacent bits.
	// See "Hacker's Delight", Chap. 5: Counting Bits.
	// The following pattern shows the general approach:
	//
	//   x = x>>1&(m0&m) + x&(m0&m)
	//   x = x>>2&(m1&m) + x&(m1&m)
	//   x = x>>4&(m2&m) + x&(m2&m)
	//   x = x>>8&(m3&m) + x&(m3&m)
	//   x = x>>16&(m4&m) + x&(m4&m)
	//   x = x>>32&(m5&m) + x&(m5&m)
	//   return int(x)
	//
	// Masking (& operations) can be left away when there's no
	// danger that a field's sum will carry over into the next
	// field: Since the result cannot be > 64, 8 bits is enough
	// and we can ignore the masks for the shifts by 8 and up.
	// Per "Hacker's Delight", the first line can be simplified
	// more, but it saves at best one instruction, so we leave
	// it alone for clarity.
	const m = 1<<64 - 1
	x = x>>1&(m0&m) + x&(m0&m)
	x = x>>2&(m1&m) + x&(m1&m)
	x = (x>>4 + x) & (m2 & m)
	x += x >> 8
	x += x >> 16
	x += x >> 32
	return int(x) & (1<<7 - 1)
}

// --- RotateLeft ---

// RotateLeft returns the value of x rotated left by k bits; k must not be negative.
func RotateLeft(x uint, k int) uint {
	if UintSize == 32 {
		return uint(RotateLeft32(uint32(x), k))
	}
	return uint(RotateLeft64(uint64(x), k))
}

// RotateLeft8 returns the value of x rotated left by k bits; k must not be negative.
func RotateLeft8(x uint8, k int) uint8 {
	if k < 0 {
		panic("negative rotation count")
	}
	const n = 8
	s := uint(k) & (n - 1)
	return x<<s | x>>(n-s)
}

// RotateLeft16 returns the value of x rotated left by k bits; k must not be negative.
func RotateLeft16(x uint16, k int) uint16 {
	if k < 0 {
		panic("negative rotation count")
	}
	const n = 16
	s := uint(k) & (n - 1)
	return x<<s | x>>(n-s)
}

// RotateLeft32 returns the value of x rotated left by k bits; k must not be negative.
func RotateLeft32(x uint32, k int) uint32 {
	if k < 0 {
		panic("negative rotation count")
	}
	const n = 32
	s := uint(k) & (n - 1)
	return x<<s | x>>(n-s)
}

// RotateLeft64 returns the value of x rotated left by k bits; k must not be negative.
func RotateLeft64(x uint64, k int) uint64 {
	if k < 0 {
		panic("negative rotation count")
	}
	const n = 64
	s := uint(k) & (n - 1)
	return x<<s | x>>(n-s)
}

// --- RotateRight ---

// RotateRight returns the value of x rotated left by k bits; k must not be negative.
func RotateRight(x uint, k int) uint {
	if UintSize == 32 {
		return uint(RotateRight32(uint32(x), k))
	}
	return uint(RotateRight64(uint64(x), k))
}

// RotateRight8 returns the value of x rotated left by k bits; k must not be negative.
func RotateRight8(x uint8, k int) uint8 {
	if k < 0 {
		panic("negative rotation count")
	}
	const n = 8
	s := uint(k) & (n - 1)
	return x<<(n-s) | x>>s
}

// RotateRight16 returns the value of x rotated left by k bits; k must not be negative.
func RotateRight16(x uint16, k int) uint16 {
	if k < 0 {
		panic("negative rotation count")
	}
	const n = 16
	s := uint(k) & (n - 1)
	return x<<(n-s) | x>>s
}

// RotateRight32 returns the value of x rotated left by k bits; k must not be negative.
func RotateRight32(x uint32, k int) uint32 {
	if k < 0 {
		panic("negative rotation count")
	}
	const n = 32
	s := uint(k) & (n - 1)
	return x<<(n-s) | x>>s
}

// RotateRight64 returns the value of x rotated left by k bits; k must not be negative.
func RotateRight64(x uint64, k int) uint64 {
	if k < 0 {
		panic("negative rotation count")
	}
	const n = 64
	s := uint(k) & (n - 1)
	return x<<(n-s) | x>>s
}

// --- Reverse ---

// Reverse returns the value of x with its bits in reversed order.
func Reverse(x uint) uint {
	if UintSize == 32 {
		return uint(Reverse32(uint32(x)))
	}
	return uint(Reverse64(uint64(x)))
}

// Reverse8 returns the value of x with its bits in reversed order.
func Reverse8(x uint8) uint8 {
	const m = 1<<8 - 1
	x = x>>1&(m0&m) | x&(m0&m)<<1
	x = x>>2&(m1&m) | x&(m1&m)<<2
	return x>>4 | x<<4
}

// Reverse16 returns the value of x with its bits in reversed order.
func Reverse16(x uint16) uint16 {
	const m = 1<<16 - 1
	x = x>>1&(m0&m) | x&(m0&m)<<1
	x = x>>2&(m1&m) | x&(m1&m)<<2
	x = x>>4&(m2&m) | x&(m2&m)<<4
	return x>>8 | x<<8
}

// Reverse32 returns the value of x with its bits in reversed order.
func Reverse32(x uint32) uint32 {
	const m = 1<<32 - 1
	x = x>>1&(m0&m) | x&(m0&m)<<1
	x = x>>2&(m1&m) | x&(m1&m)<<2
	x = x>>4&(m2&m) | x&(m2&m)<<4
	x = x>>8&(m3&m) | x&(m3&m)<<8
	return x>>16 | x<<16
}

// Reverse64 returns the value of x with its bits in reversed order.
func Reverse64(x uint64) uint64 {
	const m = 1<<64 - 1
	x = x>>1&(m0&m) | x&(m0&m)<<1
	x = x>>2&(m1&m) | x&(m1&m)<<2
	x = x>>4&(m2&m) | x&(m2&m)<<4
	x = x>>8&(m3&m) | x&(m3&m)<<8
	x = x>>16&(m4&m) | x&(m4&m)<<16
	return x>>32 | x<<32
}

// --- ReverseBytes ---

// ReverseBytes returns the value of x with its bytes in reversed order.
func ReverseBytes(x uint) uint {
	if UintSize == 32 {
		return uint(ReverseBytes32(uint32(x)))
	}
	return uint(ReverseBytes64(uint64(x)))
}

// ReverseBytes16 returns the value of x with its bytes in reversed order.
func ReverseBytes16(x uint16) uint16 {
	return x>>8 | x<<8
}

// ReverseBytes32 returns the value of x with its bytes in reversed order.
func ReverseBytes32(x uint32) uint32 {
	const m = 1<<32 - 1
	x = x>>8&(m3&m) | x&(m3&m)<<8
	return x>>16 | x<<16
}

// ReverseBytes64 returns the value of x with its bytes in reversed order.
func ReverseBytes64(x uint64) uint64 {
	const m = 1<<64 - 1
	x = x>>8&(m3&m) | x&(m3&m)<<8
	x = x>>16&(m4&m) | x&(m4&m)<<16
	return x>>32 | x<<32
}

// --- Len ---

// Len returns the minimum number of bits required to represent x; the result is 0 for x == 0.
func Len(x uint) int { return blen(uint64(x)) }

// Len8 returns the minimum number of bits required to represent x; the result is 0 for x == 0.
func Len8(x uint8) int { return blen(uint64(x)) }

// Len16 returns the minimum number of bits required to represent x; the result is 0 for x == 0.
func Len16(x uint16) int { return blen(uint64(x)) }

// Len32 returns the minimum number of bits required to represent x; the result is 0 for x == 0.
func Len32(x uint32) int { return blen(uint64(x)) }

// Len64 returns the minimum number of bits required to represent x; the result is 0 for x == 0.
func Len64(x uint64) int { return blen(uint64(x)) }
<|endoftext|>


<commit_before><commit_msg>fs/tests: coverage for longer symlink resolves.<commit_after><|endoftext|>