<commit_before>// Copyright 2015 The LUCI 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 cache

import (
	"container/list"
	"crypto"
	"encoding/json"
	"errors"
	"fmt"

	"go.chromium.org/luci/common/data/text/units"
	"go.chromium.org/luci/common/isolated"
)

// entry is an entry in the orderedDict.
type entry struct {
	key   isolated.HexDigest
	value units.Size
}

func (e *entry) MarshalJSON() ([]byte, error) {
	// encode as a tuple.
	return json.Marshal([]interface{}{e.key, e.value})
}

func (e *entry) UnmarshalJSON(data []byte) error {
	// decode from tuple.
	var elems []interface{}
	if err := json.Unmarshal(data, &elems); err != nil {
		return fmt.Errorf("invalid entry: %s: %s", err, string(data))
	}
	if len(elems) != 2 {
		return fmt.Errorf("invalid entry: expected 2 items: %s", string(data))
	}
	if key, ok := elems[0].(string); ok {
		e.key = isolated.HexDigest(key)
		if value, ok := elems[1].(float64); ok {
			e.value = units.Size(value)
		} else {
			return fmt.Errorf("invalid entry: expected value to be number: %s", string(data))
		}
	} else {
		return fmt.Errorf("invalid entry: expected key to be string: %s", string(data))
	}
	return nil
}

// orderedDict implements a dict that keeps ordering.
type orderedDict struct {
	ll      *list.List
	entries map[isolated.HexDigest]*list.Element
}

func makeOrderedDict() orderedDict {
	return orderedDict{
		ll:      list.New(),
		entries: map[isolated.HexDigest]*list.Element{},
	}
}

// keys returns the keys in order.
func (o *orderedDict) keys() isolated.HexDigests {
	out := make(isolated.HexDigests, 0, o.length())
	for e := o.ll.Front(); e != nil; e = e.Next() {
		out = append(out, e.Value.(*entry).key)
	}
	return out
}

func (o *orderedDict) pop(key isolated.HexDigest) units.Size {
	if e, hit := o.entries[key]; hit {
		return o.removeElement(e).value
	}
	return 0
}

func (o *orderedDict) popOldest() (isolated.HexDigest, units.Size) {
	if e := o.ll.Back(); e != nil {
		entry := o.removeElement(e)
		return entry.key, entry.value
	}
	return "", 0
}

func (o *orderedDict) removeElement(e *list.Element) *entry {
	o.ll.Remove(e)
	kv := e.Value.(*entry)
	delete(o.entries, kv.key)
	return kv
}

func (o *orderedDict) length() int {
	return o.ll.Len()
}

func (o *orderedDict) pushFront(key isolated.HexDigest, value units.Size) {
	if e, ok := o.entries[key]; ok {
		o.ll.MoveToFront(e)
		e.Value.(*entry).value = value
		return
	}
	o.entries[key] = o.ll.PushFront(&entry{key, value})
}

func (o *orderedDict) pushBack(key isolated.HexDigest, value units.Size) {
	if e, ok := o.entries[key]; ok {
		o.ll.MoveToBack(e)
		e.Value.(*entry).value = value
		return
	}
	o.entries[key] = o.ll.PushBack(&entry{key, value})
}

// serialized returns all the items in order.
func (o *orderedDict) serialized() []entry {
	out := make([]entry, 0, o.length())
	for e := o.ll.Front(); e != nil; e = e.Next() {
		out = append(out, *e.Value.(*entry))
	}
	return out
}

// lruDict is a dictionary that evicts least recently used items. It is a
// higher level than orderedDict.
//
// Designed to be serialized as JSON on disk.
type lruDict struct {
	h     crypto.Hash
	items orderedDict // ordered key -> value mapping, newest items at the bottom.
	dirty bool        // true if was modified after loading until it is marshaled.
	sum   units.Size  // sum of all the values.
}

func makeLRUDict(namespace string) lruDict {
	return lruDict{
		h:     isolated.GetHash(namespace),
		items: makeOrderedDict(),
	}
}

func (l *lruDict) IsDirty() bool {
	return l.dirty
}

func (l *lruDict) keys() isolated.HexDigests {
	return l.items.keys()
}

func (l *lruDict) length() int {
	return l.items.length()
}

func (l *lruDict) pop(key isolated.HexDigest) units.Size {
	out := l.items.pop(key)
	l.sum -= out
	l.dirty = true
	return out
}

func (l *lruDict) popOldest() (isolated.HexDigest, units.Size) {
	k, v := l.items.popOldest()
	l.sum -= v
	if k != "" {
		l.dirty = true
	}
	return k, v
}

func (l *lruDict) pushFront(key isolated.HexDigest, value units.Size) {
	l.items.pushFront(key, value)
	l.sum += value
	l.dirty = true
}

func (l *lruDict) touch(key isolated.HexDigest) {
	l.items.pushFront(key, l.items.pop(key))
	l.dirty = true
}

type serializedLRUDict struct {
	Version int     // 1.
	Algo    string  // "sha-1".
	Items   []entry // ordered key -> value mapping in order.
}

func (l *lruDict) MarshalJSON() ([]byte, error) {
	s := &serializedLRUDict{
		Version: 1,
		Algo:    "sha-1",
		Items:   l.items.serialized(),
	}
	// Not strictly true but #closeneough.
	content, err := json.Marshal(s)
	if err == nil {
		l.dirty = false
	}
	return content, err
}

func (l *lruDict) UnmarshalJSON(data []byte) error {
	s := &serializedLRUDict{}
	if err := json.Unmarshal(data, &s); err != nil {
		return err
	}
	if s.Version != 1 {
		return errors.New("invalid lru dict version")
	}
	if s.Algo != "sha-1" {
		return errors.New("invalid lru dict algo")
	}
	l.sum = 0
	for _, e := range s.Items {
		if !e.key.Validate(l.h) {
			return fmt.Errorf("invalid entry: %s", e.key)
		}
		l.items.pushBack(e.key, e.value)
		l.sum += e.value
	}
	l.dirty = false
	return nil
}
<commit_msg>cache: make error more verbose<commit_after>// Copyright 2015 The LUCI 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 cache

import (
	"container/list"
	"crypto"
	"encoding/json"
	"fmt"

	"go.chromium.org/luci/common/data/text/units"
	"go.chromium.org/luci/common/isolated"
)

// entry is an entry in the orderedDict.
type entry struct {
	key   isolated.HexDigest
	value units.Size
}

func (e *entry) MarshalJSON() ([]byte, error) {
	// encode as a tuple.
	return json.Marshal([]interface{}{e.key, e.value})
}

func (e *entry) UnmarshalJSON(data []byte) error {
	// decode from tuple.
	var elems []interface{}
	if err := json.Unmarshal(data, &elems); err != nil {
		return fmt.Errorf("invalid entry: %s: %s", err, string(data))
	}
	if len(elems) != 2 {
		return fmt.Errorf("invalid entry: expected 2 items: %s", string(data))
	}
	if key, ok := elems[0].(string); ok {
		e.key = isolated.HexDigest(key)
		if value, ok := elems[1].(float64); ok {
			e.value = units.Size(value)
		} else {
			return fmt.Errorf("invalid entry: expected value to be number: %s", string(data))
		}
	} else {
		return fmt.Errorf("invalid entry: expected key to be string: %s", string(data))
	}
	return nil
}

// orderedDict implements a dict that keeps ordering.
type orderedDict struct {
	ll      *list.List
	entries map[isolated.HexDigest]*list.Element
}

func makeOrderedDict() orderedDict {
	return orderedDict{
		ll:      list.New(),
		entries: map[isolated.HexDigest]*list.Element{},
	}
}

// keys returns the keys in order.
func (o *orderedDict) keys() isolated.HexDigests {
	out := make(isolated.HexDigests, 0, o.length())
	for e := o.ll.Front(); e != nil; e = e.Next() {
		out = append(out, e.Value.(*entry).key)
	}
	return out
}

func (o *orderedDict) pop(key isolated.HexDigest) units.Size {
	if e, hit := o.entries[key]; hit {
		return o.removeElement(e).value
	}
	return 0
}

func (o *orderedDict) popOldest() (isolated.HexDigest, units.Size) {
	if e := o.ll.Back(); e != nil {
		entry := o.removeElement(e)
		return entry.key, entry.value
	}
	return "", 0
}

func (o *orderedDict) removeElement(e *list.Element) *entry {
	o.ll.Remove(e)
	kv := e.Value.(*entry)
	delete(o.entries, kv.key)
	return kv
}

func (o *orderedDict) length() int {
	return o.ll.Len()
}

func (o *orderedDict) pushFront(key isolated.HexDigest, value units.Size) {
	if e, ok := o.entries[key]; ok {
		o.ll.MoveToFront(e)
		e.Value.(*entry).value = value
		return
	}
	o.entries[key] = o.ll.PushFront(&entry{key, value})
}

func (o *orderedDict) pushBack(key isolated.HexDigest, value units.Size) {
	if e, ok := o.entries[key]; ok {
		o.ll.MoveToBack(e)
		e.Value.(*entry).value = value
		return
	}
	o.entries[key] = o.ll.PushBack(&entry{key, value})
}

// serialized returns all the items in order.
func (o *orderedDict) serialized() []entry {
	out := make([]entry, 0, o.length())
	for e := o.ll.Front(); e != nil; e = e.Next() {
		out = append(out, *e.Value.(*entry))
	}
	return out
}

// lruDict is a dictionary that evicts least recently used items. It is a
// higher level than orderedDict.
//
// Designed to be serialized as JSON on disk.
type lruDict struct {
	h     crypto.Hash
	items orderedDict // ordered key -> value mapping, newest items at the bottom.
	dirty bool        // true if was modified after loading until it is marshaled.
	sum   units.Size  // sum of all the values.
}

func makeLRUDict(namespace string) lruDict {
	return lruDict{
		h:     isolated.GetHash(namespace),
		items: makeOrderedDict(),
	}
}

func (l *lruDict) IsDirty() bool {
	return l.dirty
}

func (l *lruDict) keys() isolated.HexDigests {
	return l.items.keys()
}

func (l *lruDict) length() int {
	return l.items.length()
}

func (l *lruDict) pop(key isolated.HexDigest) units.Size {
	out := l.items.pop(key)
	l.sum -= out
	l.dirty = true
	return out
}

func (l *lruDict) popOldest() (isolated.HexDigest, units.Size) {
	k, v := l.items.popOldest()
	l.sum -= v
	if k != "" {
		l.dirty = true
	}
	return k, v
}

func (l *lruDict) pushFront(key isolated.HexDigest, value units.Size) {
	l.items.pushFront(key, value)
	l.sum += value
	l.dirty = true
}

func (l *lruDict) touch(key isolated.HexDigest) {
	l.items.pushFront(key, l.items.pop(key))
	l.dirty = true
}

type serializedLRUDict struct {
	Version int     // 1.
	Algo    string  // "sha-1".
	Items   []entry // ordered key -> value mapping in order.
}

const currentVersion = 1

func (l *lruDict) MarshalJSON() ([]byte, error) {
	s := &serializedLRUDict{
		Version: currentVersion,
		Algo:    "sha-1",
		Items:   l.items.serialized(),
	}
	// Not strictly true but #closeneough.
	content, err := json.Marshal(s)
	if err == nil {
		l.dirty = false
	}
	return content, err
}

func (l *lruDict) UnmarshalJSON(data []byte) error {
	s := &serializedLRUDict{}
	if err := json.Unmarshal(data, &s); err != nil {
		return err
	}

	if s.Version != currentVersion {
		return fmt.Errorf("invalid lru dict version %d instead of current version %d", s.Version, currentVersion)
	}
	if s.Algo != "sha-1" {
		return fmt.Errorf("invalid lru dict algo: %s", s.Algo)
	}
	l.sum = 0
	for _, e := range s.Items {
		if !e.key.Validate(l.h) {
			return fmt.Errorf("invalid entry: %s", e.key)
		}
		l.items.pushBack(e.key, e.value)
		l.sum += e.value
	}
	l.dirty = false
	return nil
}
<|endoftext|>


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

package itemtree

import (
	"fmt"
	"github.com/andreaskoch/allmark2/common/route"
	"github.com/andreaskoch/allmark2/common/tree"
	"github.com/andreaskoch/allmark2/common/tree/treeutil"
	"github.com/andreaskoch/allmark2/model"
)

func New() *ItemTree {
	return &ItemTree{
		*tree.New("", nil),
	}
}

type ItemTree struct {
	tree.Tree
}

func (nodeTree *ItemTree) Root() *model.Item {
	rootNode := nodeTree.Tree.Root()
	if rootNode == nil {
		return nil
	}

	return nodeToItem(rootNode)
}

func (nodeTree *ItemTree) Insert(item *model.Item) {

	if item == nil {
		return
	}

	// convert the route to a path
	path := treeutil.RouteToPath(item.Route())

	nodeTree.Tree.Insert(path, item)
}

func (itemTree *ItemTree) Delete(item *model.Item) (bool, error) {

	if item == nil {
		return false, fmt.Errorf("The supplied item is empty.")
	}

	itemRoute := item.Route()
	return itemTree.Tree.Delete(itemRoute.Components())
}

func (nodeTree *ItemTree) GetItem(route *route.Route) *model.Item {

	// locate the node
	node := nodeTree.getNode(route)
	if node == nil {
		return nil
	}

	// cast the value
	return nodeToItem(node)
}

func (nodeTree *ItemTree) GetChildItems(route *route.Route) []*model.Item {

	childItems := make([]*model.Item, 0)

	node := nodeTree.getNode(route)
	if node == nil {
		return childItems
	}

	for _, childNode := range node.Childs() {
		if item := nodeToItem(childNode); item != nil {
			childItems = append(childItems, item)
		}
	}

	return childItems
}

func (nodeTree *ItemTree) getNode(route *route.Route) *tree.Node {

	if route == nil {
		return nil
	}

	// convert the route to a path
	path := treeutil.RouteToPath(route)

	// locate the node
	node := nodeTree.Tree.GetNode(path)
	if node == nil {
		return nil
	}

	return node
}

func nodeToItem(node *tree.Node) *model.Item {
	return node.Value().(*model.Item)
}
<commit_msg>Item tree error handling<commit_after>// Copyright 2013 Andreas Koch. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package itemtree

import (
	"fmt"
	"github.com/andreaskoch/allmark2/common/route"
	"github.com/andreaskoch/allmark2/common/tree"
	"github.com/andreaskoch/allmark2/common/tree/treeutil"
	"github.com/andreaskoch/allmark2/model"
)

func New() *ItemTree {
	return &ItemTree{
		*tree.New("", nil),
	}
}

type ItemTree struct {
	tree.Tree
}

func (nodeTree *ItemTree) Root() *model.Item {
	rootNode := nodeTree.Tree.Root()
	if rootNode == nil {
		return nil
	}

	return nodeToItem(rootNode)
}

func (nodeTree *ItemTree) Insert(item *model.Item) {

	if item == nil {
		return
	}

	// convert the route to a path
	path := treeutil.RouteToPath(item.Route())

	nodeTree.Tree.Insert(path, item)
}

func (itemTree *ItemTree) Delete(item *model.Item) (bool, error) {

	if item == nil {
		return false, fmt.Errorf("The supplied item is empty.")
	}

	itemRoute := item.Route()
	return itemTree.Tree.Delete(itemRoute.Components())
}

func (nodeTree *ItemTree) GetItem(route *route.Route) *model.Item {

	// locate the node
	node := nodeTree.getNode(route)
	if node == nil {
		return nil
	}

	// cast the value
	return nodeToItem(node)
}

func (nodeTree *ItemTree) GetChildItems(route *route.Route) []*model.Item {

	childItems := make([]*model.Item, 0)

	node := nodeTree.getNode(route)
	if node == nil {
		return childItems
	}

	for _, childNode := range node.Childs() {
		item := nodeToItem(childNode)
		if item == nil {
			// todo: log error
			continue
		}

		childItems = append(childItems, item)
	}

	return childItems
}

func (nodeTree *ItemTree) getNode(route *route.Route) *tree.Node {

	if route == nil {
		return nil
	}

	// convert the route to a path
	path := treeutil.RouteToPath(route)

	// locate the node
	node := nodeTree.Tree.GetNode(path)
	if node == nil {
		return nil
	}

	return node
}

func nodeToItem(node *tree.Node) *model.Item {

	if node.Value() == nil {
		return nil
	}

	return node.Value().(*model.Item)
}
<|endoftext|>


<commit_before>package compile_test

import (
	"errors"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	bmrel "github.com/cloudfoundry/bosh-micro-cli/release"

	fakeboshcomp "github.com/cloudfoundry/bosh-micro-cli/compile/fakes"
	fakebmreal "github.com/cloudfoundry/bosh-micro-cli/release/fakes"

	. "github.com/cloudfoundry/bosh-micro-cli/compile"
)

var _ = Describe("ReleaseCompiler", func() {
	var (
		release             bmrel.Release
		releaseCompiler     ReleaseCompiler
		fakeDA              *fakebmreal.FakeDependencyAnalysis
		fakePackageCompiler *fakeboshcomp.FakePackageCompiler
	)

	BeforeEach(func() {
		fakeDA = fakebmreal.NewFakeDependencyAnalysis()
		fakePackageCompiler = fakeboshcomp.NewFakePackageCompiler()

		releaseCompiler = NewReleaseCompiler(fakeDA, fakePackageCompiler)
		release = bmrel.Release{}
	})

	Context("Compile", func() {
		Context("when the release", func() {
			var expectedPackages []*bmrel.Package

			BeforeEach(func() {
				package1 := bmrel.Package{Name: "fake-package-1"}
				package2 := bmrel.Package{Name: "fake-package-2"}

				expectedPackages = []*bmrel.Package{&package1, &package2}

				fakeDA.DeterminePackageCompilationOrderResult = []*bmrel.Package{
					&package1,
					&package2,
				}
			})

			It("determines the order to compile packages", func() {
				err := releaseCompiler.Compile(release)
				Expect(err).NotTo(HaveOccurred())
				Expect(fakeDA.DeterminePackageCompilationOrderRelease).To(Equal(release))
			})

			It("compiles each package", func() {
				err := releaseCompiler.Compile(release)
				Expect(err).NotTo(HaveOccurred())
				Expect(fakePackageCompiler.CompilePackages).To(Equal(expectedPackages))
			})

			It("compiles each package and returns error for first package", func() {
				fakePackageCompiler.CompileError = errors.New("Compilation failed")
				err := releaseCompiler.Compile(release)
				Expect(err).To(HaveOccurred())
				Expect(err.Error()).To(ContainSubstring("Package `fake-package-1' compilation failed"))
			})

			It("stops compiling after the first failures", func() {
				fakePackageCompiler.CompileError = errors.New("Compilation failed")
				err := releaseCompiler.Compile(release)
				Expect(err).To(HaveOccurred())
				Expect(len(fakePackageCompiler.CompilePackages)).To(Equal(1))
			})
		})
	})
})
<commit_msg>Change names of fakes in release_compiler_test<commit_after>package compile_test

import (
	"errors"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	bmrel "github.com/cloudfoundry/bosh-micro-cli/release"

	fakeboshcomp "github.com/cloudfoundry/bosh-micro-cli/compile/fakes"
	fakebmreal "github.com/cloudfoundry/bosh-micro-cli/release/fakes"

	. "github.com/cloudfoundry/bosh-micro-cli/compile"
)

var _ = Describe("ReleaseCompiler", func() {
	var (
		release         bmrel.Release
		releaseCompiler ReleaseCompiler
		da              *fakebmreal.FakeDependencyAnalysis
		packageCompiler *fakeboshcomp.FakePackageCompiler
	)

	BeforeEach(func() {
		da = fakebmreal.NewFakeDependencyAnalysis()
		packageCompiler = fakeboshcomp.NewFakePackageCompiler()

		releaseCompiler = NewReleaseCompiler(da, packageCompiler)
		release = bmrel.Release{}
	})

	Context("Compile", func() {
		Context("when the release", func() {
			var expectedPackages []*bmrel.Package

			BeforeEach(func() {
				package1 := bmrel.Package{Name: "fake-package-1"}
				package2 := bmrel.Package{Name: "fake-package-2"}

				expectedPackages = []*bmrel.Package{&package1, &package2}

				da.DeterminePackageCompilationOrderResult = []*bmrel.Package{
					&package1,
					&package2,
				}
			})

			It("determines the order to compile packages", func() {
				err := releaseCompiler.Compile(release)
				Expect(err).NotTo(HaveOccurred())
				Expect(da.DeterminePackageCompilationOrderRelease).To(Equal(release))
			})

			It("compiles each package", func() {
				err := releaseCompiler.Compile(release)
				Expect(err).NotTo(HaveOccurred())
				Expect(packageCompiler.CompilePackages).To(Equal(expectedPackages))
			})

			It("compiles each package and returns error for first package", func() {
				packageCompiler.CompileError = errors.New("Compilation failed")
				err := releaseCompiler.Compile(release)
				Expect(err).To(HaveOccurred())
				Expect(err.Error()).To(ContainSubstring("Package `fake-package-1' compilation failed"))
			})

			It("stops compiling after the first failures", func() {
				packageCompiler.CompileError = errors.New("Compilation failed")
				err := releaseCompiler.Compile(release)
				Expect(err).To(HaveOccurred())
				Expect(len(packageCompiler.CompilePackages)).To(Equal(1))
			})
		})
	})
})
<|endoftext|>


<commit_before>package middleware

import (
	"bytes"
	"encoding/json"
	"github.com/intervention-engine/fhir/server"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
	"net/http"
	"net/url"
	"strconv"
	"text/template"
	"time"
)

type RiskModelParameter struct {
	Category string
	Weight   float64
	Method   string
}

func RiskQueryHandler(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
	query := r.URL.Query()
	queryValues := query["_query"]
	if len(queryValues) > 0 && queryValues[0] == "risk" {
		mapFn := `function() {
  emit(this.patientid, {factType: this.type, risk: 0})
}`
		reduceSoure := `function(patient_id, values) {
  var reducedObject = {
    factType: 'risk',
    risk: 0
  }

  values.forEach(function(value) {
    {{ range . }}
    if (value.factType === '{{.Category}}') {
      {{if eq .Method "count"}}
      reducedObject.risk += 1 * {{.Weight}};
      {{ end }}
      {{if eq .Method "presence"}}
      reducedObject.risk += {{.Weight}};
      {{ end }}
    };
    {{ end }}
  });

  return reducedObject;
}`
		reduceTemplate, err := template.New("reduce").Parse(reduceSoure)
		var buffer bytes.Buffer
		rmps := handleRiskModelParameters(query)
		reduceTemplate.Execute(&buffer, rmps)
		mrJob := mgo.MapReduce{Map: mapFn, Reduce: buffer.String()}
		facts := server.Database.C("facts")

		type valueStruct struct {
			Risk int `bson:"risk"`
		}

		var result []struct {
			Id    string      `bson:"_id"`
			Value valueStruct `bson:"value"`
		}

		query := facts.Find(bson.M{"$or": []bson.M{{"enddate.time": nil}, {"enddate.time": bson.M{"$gt": time.Now()}}}})
		_, err = query.MapReduce(&mrJob, &result)

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

		json.NewEncoder(rw).Encode(result)
	} else {
		next(rw, r)
	}
}

func handleRiskModelParameters(queryParams url.Values) []RiskModelParameter {
	rmps := []RiskModelParameter{}
	categories := []string{"MedicationStatement", "Condition", "Encounter"}
	for _, category := range categories {
		method, ok := queryParams[category]
		if ok {
			rmp := RiskModelParameter{Category: category, Method: method[0]}
			weightSlice, weightPresent := queryParams[category+"Weight"]
			if weightPresent {
				weight := weightSlice[0]
				floatWeight, err := strconv.ParseFloat(weight, 64)
				if err != nil {
					rmp.Weight = 1.0
				} else {
					rmp.Weight = floatWeight
				}
			} else {
				rmp.Weight = 1.0
			}
			rmps = append(rmps, rmp)
		}
	}
	return rmps
}
<commit_msg>Fixed typo<commit_after>package middleware

import (
	"bytes"
	"encoding/json"
	"github.com/intervention-engine/fhir/server"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
	"net/http"
	"net/url"
	"strconv"
	"text/template"
	"time"
)

type RiskModelParameter struct {
	Category string
	Weight   float64
	Method   string
}

func RiskQueryHandler(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
	query := r.URL.Query()
	queryValues := query["_query"]
	if len(queryValues) > 0 && queryValues[0] == "risk" {
		mapFn := `function() {
  emit(this.patientid, {factType: this.type, risk: 0})
}`
		reduceSource := `function(patient_id, values) {
  var reducedObject = {
    factType: 'risk',
    risk: 0
  }

  values.forEach(function(value) {
    {{ range . }}
    if (value.factType === '{{.Category}}') {
      {{if eq .Method "count"}}
      reducedObject.risk += 1 * {{.Weight}};
      {{ end }}
      {{if eq .Method "presence"}}
      reducedObject.risk += {{.Weight}};
      {{ end }}
    };
    {{ end }}
  });

  return reducedObject;
}`
		reduceTemplate, err := template.New("reduce").Parse(reduceSource)
		var buffer bytes.Buffer
		rmps := handleRiskModelParameters(query)
		reduceTemplate.Execute(&buffer, rmps)
		mrJob := mgo.MapReduce{Map: mapFn, Reduce: buffer.String()}
		facts := server.Database.C("facts")

		type valueStruct struct {
			Risk int `bson:"risk"`
		}

		var result []struct {
			Id    string      `bson:"_id"`
			Value valueStruct `bson:"value"`
		}

		query := facts.Find(bson.M{"$or": []bson.M{{"enddate.time": nil}, {"enddate.time": bson.M{"$gt": time.Now()}}}})
		_, err = query.MapReduce(&mrJob, &result)

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

		json.NewEncoder(rw).Encode(result)
	} else {
		next(rw, r)
	}
}

func handleRiskModelParameters(queryParams url.Values) []RiskModelParameter {
	rmps := []RiskModelParameter{}
	categories := []string{"MedicationStatement", "Condition", "Encounter"}
	for _, category := range categories {
		method, ok := queryParams[category]
		if ok {
			rmp := RiskModelParameter{Category: category, Method: method[0]}
			weightSlice, weightPresent := queryParams[category+"Weight"]
			if weightPresent {
				weight := weightSlice[0]
				floatWeight, err := strconv.ParseFloat(weight, 64)
				if err != nil {
					rmp.Weight = 1.0
				} else {
					rmp.Weight = floatWeight
				}
			} else {
				rmp.Weight = 1.0
			}
			rmps = append(rmps, rmp)
		}
	}
	return rmps
}
<|endoftext|>


<commit_before>package node

import (
	"bytes"
	"crypto/tls"
	"net"
	"net/http/httptest"
	"testing"
	"time"

	"github.com/gansoi/gansoi/cluster"
	"github.com/hashicorp/raft"
)

func getStream(t *testing.T) *HTTPStream {
	core := cluster.NewCore(&cluster.Info{})
	core.Bootstrap()

	certificates, _ := core.Start()
	ca := core.CA()

	stream, err := NewHTTPStream("127.0.0.1:0", certificates, ca)
	if err != nil {
		t.Fatalf("NewHTTPStream() returned an error: %s", err.Error())
		return nil
	}

	return stream
}

func echoServer(stream *HTTPStream) {
	conn, err := stream.Accept()
	if err != nil {
		return
	}

	for {
		b := make([]byte, 1024)
		n, err := conn.Read(b)
		if err != nil {
			return
		}

		_, err = conn.Write(b[:n])
		if err != nil {
			return
		}
	}
}

func TestStreamListen(t *testing.T) {
	stream := getStream(t)
	defer stream.Close()

	server := httptest.NewUnstartedServer(stream)
	server.TLS = &tls.Config{Certificates: stream.certificates}
	server.StartTLS()
	defer server.Close()

	conn, err := stream.Dial(raft.ServerAddress(server.Listener.Addr().String()), time.Millisecond*100)
	if err != nil {
		t.Errorf("Dial() errored: %s\n", err.Error())
	}
	defer conn.Close()
}

func exchange(conn net.Conn, payload []byte) []byte {
	n, err := conn.Write(payload)
	if err != nil {
		panic(err.Error())
	}
	if n != len(payload) {
		panic("fail")
	}

	time.Sleep(time.Millisecond * 20)

	b := make([]byte, 1024)
	n, _ = conn.Read(b)

	return b[:n]
}

func TestStreamEcho(t *testing.T) {
	stream := getStream(t)
	defer stream.Close()

	server := httptest.NewUnstartedServer(stream)
	server.TLS = &tls.Config{Certificates: stream.certificates, ClientAuth: tls.RequestClientCert}
	server.StartTLS()
	defer server.Close()

	go echoServer(stream)

	conn, err := stream.Dial(raft.ServerAddress(server.Listener.Addr().String()), time.Millisecond*100)
	if err != nil {
		t.Fatalf("Dial() errored: %s\n", err.Error())
	}
	defer conn.Close()

	time.Sleep(time.Millisecond * 20) // Give echoServer some time to accept.

	payload := []byte("Hello 123")
	result := exchange(conn, payload)

	if bytes.Compare(payload, result) != 0 {
		t.Errorf("Got wrong reply, got '%s', expected '%s'", result, payload)
	}

	payload = []byte("Hello hello")
	result = exchange(conn, payload)

	if bytes.Compare(payload, result) != 0 {
		t.Errorf("Got wrong reply, got '%s', expected '%s'", result, payload)
	}
}

var _ raft.StreamLayer = (*HTTPStream)(nil)
<commit_msg>Retry read in exchange() if needed.<commit_after>package node

import (
	"bytes"
	"crypto/tls"
	"net"
	"net/http/httptest"
	"testing"
	"time"

	"github.com/gansoi/gansoi/cluster"
	"github.com/hashicorp/raft"
)

func getStream(t *testing.T) *HTTPStream {
	core := cluster.NewCore(&cluster.Info{})
	core.Bootstrap()

	certificates, _ := core.Start()
	ca := core.CA()

	stream, err := NewHTTPStream("127.0.0.1:0", certificates, ca)
	if err != nil {
		t.Fatalf("NewHTTPStream() returned an error: %s", err.Error())
		return nil
	}

	return stream
}

func echoServer(stream *HTTPStream) {
	conn, err := stream.Accept()
	if err != nil {
		return
	}

	for {
		b := make([]byte, 1024)
		n, err := conn.Read(b)
		if err != nil {
			return
		}

		_, err = conn.Write(b[:n])
		if err != nil {
			return
		}
	}
}

func TestStreamListen(t *testing.T) {
	stream := getStream(t)
	defer stream.Close()

	server := httptest.NewUnstartedServer(stream)
	server.TLS = &tls.Config{Certificates: stream.certificates}
	server.StartTLS()
	defer server.Close()

	conn, err := stream.Dial(raft.ServerAddress(server.Listener.Addr().String()), time.Millisecond*100)
	if err != nil {
		t.Errorf("Dial() errored: %s\n", err.Error())
	}
	defer conn.Close()
}

func exchange(conn net.Conn, payload []byte) []byte {
	n, err := conn.Write(payload)
	if err != nil {
		panic(err.Error())
	}
	if n != len(payload) {
		panic("fail")
	}

	b := make([]byte, 1024)
	for {
		// Busy waiting.
		n, _ = conn.Read(b)
		if n > 0 {
			break
		}
	}

	return b[:n]
}

func TestStreamEcho(t *testing.T) {
	stream := getStream(t)
	defer stream.Close()

	server := httptest.NewUnstartedServer(stream)
	server.TLS = &tls.Config{Certificates: stream.certificates, ClientAuth: tls.RequestClientCert}
	server.StartTLS()
	defer server.Close()

	go echoServer(stream)

	conn, err := stream.Dial(raft.ServerAddress(server.Listener.Addr().String()), time.Millisecond*100)
	if err != nil {
		t.Fatalf("Dial() errored: %s\n", err.Error())
	}
	defer conn.Close()

	time.Sleep(time.Millisecond * 20) // Give echoServer some time to accept.

	payload := []byte("Hello 123")
	result := exchange(conn, payload)

	if bytes.Compare(payload, result) != 0 {
		t.Errorf("Got wrong reply, got '%s', expected '%s'", result, payload)
	}

	payload = []byte("Hello hello")
	result = exchange(conn, payload)

	if bytes.Compare(payload, result) != 0 {
		t.Errorf("Got wrong reply, got '%s', expected '%s'", result, payload)
	}
}

var _ raft.StreamLayer = (*HTTPStream)(nil)
<|endoftext|>


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

package orchestrator

import (
	"github.com/andreaskoch/allmark2/common/index"
	"github.com/andreaskoch/allmark2/common/paths"
	"github.com/andreaskoch/allmark2/common/route"
	"github.com/andreaskoch/allmark2/common/tree/routertree"
	"github.com/andreaskoch/allmark2/ui/web/view/viewmodel"
)

func NewTreeOrchestrator(itemIndex *index.Index) TreeOrchestrator {
	return TreeOrchestrator{
		itemIndex: itemIndex,
	}
}

type TreeOrchestrator struct {
	itemIndex *index.Index
}

func (orchestrator *TreeOrchestrator) GetTree(pathProvider paths.Pather, routerItems []route.Router) *viewmodel.TreeNode {

	// convert router items to tree
	tree := routertree.New()
	for _, item := range routerItems {
		tree.InsertItem(item)
	}

	// convert tree to viewmodel
	rootItem := tree.GetRootItem()
	if rootItem == nil {
		return nil
	}

	return convertRouterItemToViewModel(*tree, rootItem)
}

func convertRouterItemToViewModel(tree routertree.RouterTree, rootItem route.Router) *viewmodel.TreeNode {

	treeNodeModel := &viewmodel.TreeNode{}

	treeNodeModel.Route = rootItem.Route().Value()
	childs := tree.GetChildItems(rootItem.Route())
	for _, child := range childs {
		childModel := convertRouterItemToViewModel(tree, child)
		if childModel == nil {
			continue
		}

		treeNodeModel.Childs = append(treeNodeModel.Childs, *childModel)
	}

	return treeNodeModel
}
<commit_msg>The TreeOrchestrator does not need a reference to the item index<commit_after>// Copyright 2013 Andreas Koch. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package orchestrator

import (
	"github.com/andreaskoch/allmark2/common/paths"
	"github.com/andreaskoch/allmark2/common/route"
	"github.com/andreaskoch/allmark2/common/tree/routertree"
	"github.com/andreaskoch/allmark2/ui/web/view/viewmodel"
)

func NewTreeOrchestrator() TreeOrchestrator {
	return TreeOrchestrator{}
}

type TreeOrchestrator struct {
}

func (orchestrator *TreeOrchestrator) GetTree(pathProvider paths.Pather, routerItems []route.Router) *viewmodel.TreeNode {

	// convert router items to tree
	tree := routertree.New()
	for _, item := range routerItems {
		tree.InsertItem(item)
	}

	// convert tree to viewmodel
	rootItem := tree.GetRootItem()
	if rootItem == nil {
		return nil
	}

	return convertRouterItemToViewModel(*tree, rootItem)
}

func convertRouterItemToViewModel(tree routertree.RouterTree, rootItem route.Router) *viewmodel.TreeNode {

	treeNodeModel := &viewmodel.TreeNode{}

	treeNodeModel.Route = rootItem.Route().Value()
	childs := tree.GetChildItems(rootItem.Route())
	for _, child := range childs {
		childModel := convertRouterItemToViewModel(tree, child)
		if childModel == nil {
			continue
		}

		treeNodeModel.Childs = append(treeNodeModel.Childs, *childModel)
	}

	return treeNodeModel
}
<|endoftext|>


<commit_before>package image // import "github.com/docker/docker/image"

import (
	"encoding/json"
	"errors"
	"io"
	"runtime"
	"strings"
	"time"

	"github.com/docker/docker/api/types/container"
	"github.com/docker/docker/dockerversion"
	"github.com/docker/docker/layer"
	"github.com/opencontainers/go-digest"
)

// ID is the content-addressable ID of an image.
type ID digest.Digest

func (id ID) String() string {
	return id.Digest().String()
}

// Digest converts ID into a digest
func (id ID) Digest() digest.Digest {
	return digest.Digest(id)
}

// IDFromDigest creates an ID from a digest
func IDFromDigest(digest digest.Digest) ID {
	return ID(digest)
}

// V1Image stores the V1 image configuration.
type V1Image struct {
	// ID is a unique 64 character identifier of the image
	ID string `json:"id,omitempty"`
	// Parent is the ID of the parent image
	Parent string `json:"parent,omitempty"`
	// Comment is the commit message that was set when committing the image
	Comment string `json:"comment,omitempty"`
	// Created is the timestamp at which the image was created
	Created time.Time `json:"created"`
	// Container is the id of the container used to commit
	Container string `json:"container,omitempty"`
	// ContainerConfig is the configuration of the container that is committed into the image
	ContainerConfig container.Config `json:"container_config,omitempty"`
	// DockerVersion specifies the version of Docker that was used to build the image
	DockerVersion string `json:"docker_version,omitempty"`
	// Author is the name of the author that was specified when committing the image
	Author string `json:"author,omitempty"`
	// Config is the configuration of the container received from the client
	Config *container.Config `json:"config,omitempty"`
	// Architecture is the hardware that the image is built and runs on
	Architecture string `json:"architecture,omitempty"`
	// OS is the operating system used to build and run the image
	OS string `json:"os,omitempty"`
	// Size is the total size of the image including all layers it is composed of
	Size int64 `json:",omitempty"`
}

// Image stores the image configuration
type Image struct {
	V1Image
	Parent     ID        `json:"parent,omitempty"`
	RootFS     *RootFS   `json:"rootfs,omitempty"`
	History    []History `json:"history,omitempty"`
	OSVersion  string    `json:"os.version,omitempty"`
	OSFeatures []string  `json:"os.features,omitempty"`

	// rawJSON caches the immutable JSON associated with this image.
	rawJSON []byte

	// computedID is the ID computed from the hash of the image config.
	// Not to be confused with the legacy V1 ID in V1Image.
	computedID ID
}

// RawJSON returns the immutable JSON associated with the image.
func (img *Image) RawJSON() []byte {
	return img.rawJSON
}

// ID returns the image's content-addressable ID.
func (img *Image) ID() ID {
	return img.computedID
}

// ImageID stringifies ID.
func (img *Image) ImageID() string {
	return img.ID().String()
}

// RunConfig returns the image's container config.
func (img *Image) RunConfig() *container.Config {
	return img.Config
}

// OperatingSystem returns the image's operating system. If not populated, defaults to the host runtime OS.
func (img *Image) OperatingSystem() string {
	os := img.OS
	if os == "" {
		os = runtime.GOOS
	}
	return os
}

// MarshalJSON serializes the image to JSON. It sorts the top-level keys so
// that JSON that's been manipulated by a push/pull cycle with a legacy
// registry won't end up with a different key order.
func (img *Image) MarshalJSON() ([]byte, error) {
	type MarshalImage Image

	pass1, err := json.Marshal(MarshalImage(*img))
	if err != nil {
		return nil, err
	}

	var c map[string]*json.RawMessage
	if err := json.Unmarshal(pass1, &c); err != nil {
		return nil, err
	}
	return json.Marshal(c)
}

// ChildConfig is the configuration to apply to an Image to create a new
// Child image. Other properties of the image are copied from the parent.
type ChildConfig struct {
	ContainerID     string
	Author          string
	Comment         string
	DiffID          layer.DiffID
	ContainerConfig *container.Config
	Config          *container.Config
}

// NewChildImage creates a new Image as a child of this image.
func NewChildImage(img *Image, child ChildConfig, platform string) *Image {
	isEmptyLayer := layer.IsEmpty(child.DiffID)
	var rootFS *RootFS
	if img.RootFS != nil {
		rootFS = img.RootFS.Clone()
	} else {
		rootFS = NewRootFS()
	}

	if !isEmptyLayer {
		rootFS.Append(child.DiffID)
	}
	imgHistory := NewHistory(
		child.Author,
		child.Comment,
		strings.Join(child.ContainerConfig.Cmd, " "),
		isEmptyLayer)

	return &Image{
		V1Image: V1Image{
			DockerVersion:   dockerversion.Version,
			Config:          child.Config,
			Architecture:    runtime.GOARCH,
			OS:              platform,
			Container:       child.ContainerID,
			ContainerConfig: *child.ContainerConfig,
			Author:          child.Author,
			Created:         imgHistory.Created,
		},
		RootFS:     rootFS,
		History:    append(img.History, imgHistory),
		OSFeatures: img.OSFeatures,
		OSVersion:  img.OSVersion,
	}
}

// History stores build commands that were used to create an image
type History struct {
	// Created is the timestamp at which the image was created
	Created time.Time `json:"created"`
	// Author is the name of the author that was specified when committing the image
	Author string `json:"author,omitempty"`
	// CreatedBy keeps the Dockerfile command used while building the image
	CreatedBy string `json:"created_by,omitempty"`
	// Comment is the commit message that was set when committing the image
	Comment string `json:"comment,omitempty"`
	// EmptyLayer is set to true if this history item did not generate a
	// layer. Otherwise, the history item is associated with the next
	// layer in the RootFS section.
	EmptyLayer bool `json:"empty_layer,omitempty"`
}

// NewHistory creates a new history struct from arguments, and sets the created
// time to the current time in UTC
func NewHistory(author, comment, createdBy string, isEmptyLayer bool) History {
	return History{
		Author:     author,
		Created:    time.Now().UTC(),
		CreatedBy:  createdBy,
		Comment:    comment,
		EmptyLayer: isEmptyLayer,
	}
}

// Exporter provides interface for loading and saving images
type Exporter interface {
	Load(io.ReadCloser, io.Writer, bool) error
	// TODO: Load(net.Context, io.ReadCloser, <- chan StatusMessage) error
	Save([]string, io.Writer) error
}

// NewFromJSON creates an Image configuration from json.
func NewFromJSON(src []byte) (*Image, error) {
	img := &Image{}

	if err := json.Unmarshal(src, img); err != nil {
		return nil, err
	}
	if img.RootFS == nil {
		return nil, errors.New("invalid image JSON, no RootFS key")
	}

	img.rawJSON = src

	return img, nil
}
<commit_msg>Dockerbuilder: use the arch info from base image<commit_after>package image // import "github.com/docker/docker/image"

import (
	"encoding/json"
	"errors"
	"io"
	"runtime"
	"strings"
	"time"

	"github.com/docker/docker/api/types/container"
	"github.com/docker/docker/dockerversion"
	"github.com/docker/docker/layer"
	"github.com/opencontainers/go-digest"
)

// ID is the content-addressable ID of an image.
type ID digest.Digest

func (id ID) String() string {
	return id.Digest().String()
}

// Digest converts ID into a digest
func (id ID) Digest() digest.Digest {
	return digest.Digest(id)
}

// IDFromDigest creates an ID from a digest
func IDFromDigest(digest digest.Digest) ID {
	return ID(digest)
}

// V1Image stores the V1 image configuration.
type V1Image struct {
	// ID is a unique 64 character identifier of the image
	ID string `json:"id,omitempty"`
	// Parent is the ID of the parent image
	Parent string `json:"parent,omitempty"`
	// Comment is the commit message that was set when committing the image
	Comment string `json:"comment,omitempty"`
	// Created is the timestamp at which the image was created
	Created time.Time `json:"created"`
	// Container is the id of the container used to commit
	Container string `json:"container,omitempty"`
	// ContainerConfig is the configuration of the container that is committed into the image
	ContainerConfig container.Config `json:"container_config,omitempty"`
	// DockerVersion specifies the version of Docker that was used to build the image
	DockerVersion string `json:"docker_version,omitempty"`
	// Author is the name of the author that was specified when committing the image
	Author string `json:"author,omitempty"`
	// Config is the configuration of the container received from the client
	Config *container.Config `json:"config,omitempty"`
	// Architecture is the hardware that the image is built and runs on
	Architecture string `json:"architecture,omitempty"`
	// OS is the operating system used to build and run the image
	OS string `json:"os,omitempty"`
	// Size is the total size of the image including all layers it is composed of
	Size int64 `json:",omitempty"`
}

// Image stores the image configuration
type Image struct {
	V1Image
	Parent     ID        `json:"parent,omitempty"`
	RootFS     *RootFS   `json:"rootfs,omitempty"`
	History    []History `json:"history,omitempty"`
	OSVersion  string    `json:"os.version,omitempty"`
	OSFeatures []string  `json:"os.features,omitempty"`

	// rawJSON caches the immutable JSON associated with this image.
	rawJSON []byte

	// computedID is the ID computed from the hash of the image config.
	// Not to be confused with the legacy V1 ID in V1Image.
	computedID ID
}

// RawJSON returns the immutable JSON associated with the image.
func (img *Image) RawJSON() []byte {
	return img.rawJSON
}

// ID returns the image's content-addressable ID.
func (img *Image) ID() ID {
	return img.computedID
}

// ImageID stringifies ID.
func (img *Image) ImageID() string {
	return img.ID().String()
}

// RunConfig returns the image's container config.
func (img *Image) RunConfig() *container.Config {
	return img.Config
}

// BaseImgArch returns the image's architecture. If not populated, defaults to the host runtime arch.
func (img *Image) BaseImgArch() string {
	arch := img.Architecture
	if arch == "" {
		arch = runtime.GOARCH
	}
	return arch
}

// OperatingSystem returns the image's operating system. If not populated, defaults to the host runtime OS.
func (img *Image) OperatingSystem() string {
	os := img.OS
	if os == "" {
		os = runtime.GOOS
	}
	return os
}

// MarshalJSON serializes the image to JSON. It sorts the top-level keys so
// that JSON that's been manipulated by a push/pull cycle with a legacy
// registry won't end up with a different key order.
func (img *Image) MarshalJSON() ([]byte, error) {
	type MarshalImage Image

	pass1, err := json.Marshal(MarshalImage(*img))
	if err != nil {
		return nil, err
	}

	var c map[string]*json.RawMessage
	if err := json.Unmarshal(pass1, &c); err != nil {
		return nil, err
	}
	return json.Marshal(c)
}

// ChildConfig is the configuration to apply to an Image to create a new
// Child image. Other properties of the image are copied from the parent.
type ChildConfig struct {
	ContainerID     string
	Author          string
	Comment         string
	DiffID          layer.DiffID
	ContainerConfig *container.Config
	Config          *container.Config
}

// NewChildImage creates a new Image as a child of this image.
func NewChildImage(img *Image, child ChildConfig, platform string) *Image {
	isEmptyLayer := layer.IsEmpty(child.DiffID)
	var rootFS *RootFS
	if img.RootFS != nil {
		rootFS = img.RootFS.Clone()
	} else {
		rootFS = NewRootFS()
	}

	if !isEmptyLayer {
		rootFS.Append(child.DiffID)
	}
	imgHistory := NewHistory(
		child.Author,
		child.Comment,
		strings.Join(child.ContainerConfig.Cmd, " "),
		isEmptyLayer)

	return &Image{
		V1Image: V1Image{
			DockerVersion:   dockerversion.Version,
			Config:          child.Config,
			Architecture:    img.BaseImgArch(),
			OS:              platform,
			Container:       child.ContainerID,
			ContainerConfig: *child.ContainerConfig,
			Author:          child.Author,
			Created:         imgHistory.Created,
		},
		RootFS:     rootFS,
		History:    append(img.History, imgHistory),
		OSFeatures: img.OSFeatures,
		OSVersion:  img.OSVersion,
	}
}

// History stores build commands that were used to create an image
type History struct {
	// Created is the timestamp at which the image was created
	Created time.Time `json:"created"`
	// Author is the name of the author that was specified when committing the image
	Author string `json:"author,omitempty"`
	// CreatedBy keeps the Dockerfile command used while building the image
	CreatedBy string `json:"created_by,omitempty"`
	// Comment is the commit message that was set when committing the image
	Comment string `json:"comment,omitempty"`
	// EmptyLayer is set to true if this history item did not generate a
	// layer. Otherwise, the history item is associated with the next
	// layer in the RootFS section.
	EmptyLayer bool `json:"empty_layer,omitempty"`
}

// NewHistory creates a new history struct from arguments, and sets the created
// time to the current time in UTC
func NewHistory(author, comment, createdBy string, isEmptyLayer bool) History {
	return History{
		Author:     author,
		Created:    time.Now().UTC(),
		CreatedBy:  createdBy,
		Comment:    comment,
		EmptyLayer: isEmptyLayer,
	}
}

// Exporter provides interface for loading and saving images
type Exporter interface {
	Load(io.ReadCloser, io.Writer, bool) error
	// TODO: Load(net.Context, io.ReadCloser, <- chan StatusMessage) error
	Save([]string, io.Writer) error
}

// NewFromJSON creates an Image configuration from json.
func NewFromJSON(src []byte) (*Image, error) {
	img := &Image{}

	if err := json.Unmarshal(src, img); err != nil {
		return nil, err
	}
	if img.RootFS == nil {
		return nil, errors.New("invalid image JSON, no RootFS key")
	}

	img.rawJSON = src

	return img, nil
}
<|endoftext|>


<commit_before>package nodetable

import "testing"
import "bytes"
import "hash/crc32"
import "unsafe"

type object struct {
	key   []byte
	value int
}

func equalObject(p unsafe.Pointer, k []byte) bool {
	obj := (*object)(p)
	return bytes.Equal(obj.key, k)
}

func mkHashFun(h uint32) HashFn {
	return func([]byte) uint32 {
		return h
	}
}

func mkObject(key string, v int) *object {
	return &object{
		key:   []byte(key),
		value: v,
	}
}

func TestPointerEncode(t *testing.T) {
	o1 := unsafe.Pointer(mkObject("key", 1000))
	v := encodePointer(o1, true)
	o2 := decodePointer(v)

	if o1 != o2 {
		t.Errorf("Expected encoded value to remain the same with conflict %p!=%p", o1, o2)
	}

	v = encodePointer(o1, false)
	o2 = decodePointer(v)

	if o1 != o2 {
		t.Errorf("Expected encoded value to remain the same without conflict %p!=%p", o1, o2)
	}
}

func TestInsertFastHT(t *testing.T) {
	table := New(mkHashFun(100), equalObject)
	o1 := mkObject("key", 1000)
	table.Update(o1.key, unsafe.Pointer(o1))
	o2 := (*object)(table.Get(o1.key))
	if o2 != o1 {
		t.Errorf("Expected same object")
	}
}

func TestInsertSlowHT(t *testing.T) {
	table := New(mkHashFun(100), equalObject)
	o1 := mkObject("key1", 1000)
	o2 := mkObject("key2", 2000)
	o3 := mkObject("key3", 3000)
	table.Update(o1.key, unsafe.Pointer(o1))
	table.Update(o2.key, unsafe.Pointer(o2))
	table.Update(o3.key, unsafe.Pointer(o3))
	ro1 := (*object)(table.Get(o1.key))
	ro2 := (*object)(table.Get(o2.key))
	ro3 := (*object)(table.Get(o3.key))
	if o1 != ro1 || o2 != ro2 || o3 != ro3 {
		t.Errorf("Expected same objects %p!=%p, %p!=%p, %p!=%p", o1, ro1, o2, ro2, o3, ro3)
	}
}

func TestUpdateFastHT(t *testing.T) {
	table := New(mkHashFun(100), equalObject)
	o1 := mkObject("key", 1000)
	o2 := mkObject("key", 2000)
	updated, old := table.Update(o1.key, unsafe.Pointer(o1))
	if updated != false || old != nil {
		t.Errorf("Expected successful insert")
	}

	updated, old = table.Update(o2.key, unsafe.Pointer(o2))
	if updated != true || (*object)(old) != o1 {
		t.Errorf("Expected old object to be returned")
	}
}

func TestUpdateSlowHT(t *testing.T) {
	table := New(mkHashFun(100), equalObject)
	o1 := mkObject("key0", 1000)
	o2 := mkObject("key1", 2000)
	o3 := mkObject("key1", 6000)
	updated, old := table.Update(o1.key, unsafe.Pointer(o1))
	if updated != false || old != nil {
		t.Errorf("Expected successful insert")
	}

	table.Update(o2.key, unsafe.Pointer(o2))
	updated, old = table.Update(o3.key, unsafe.Pointer(o3))
	if updated != true || (*object)(old) != o2 {
		t.Errorf("Expected old object to be returned")
	}
}

func TestDeleteFastHT1(t *testing.T) {
	table := New(mkHashFun(100), equalObject)
	o1 := mkObject("key", 1000)
	table.Update(o1.key, unsafe.Pointer(o1))
	o2 := (*object)(table.Get(o1.key))
	if o2 != o1 {
		t.Errorf("Expected same object")
	}

	if table.Remove(o1.key) != true {
		t.Errorf("Expected successful remove")
	}

	o3 := (*object)(table.Get(o1.key))
	if o3 != nil {
		t.Errorf("Expected not-found")
	}

	if table.Remove(o1.key) == true {
		t.Errorf("Expected remove fail")
	}
}

func TestDeleteFastHT2(t *testing.T) {
	table := New(mkHashFun(100), equalObject)
	o1 := mkObject("key1", 1000)
	o2 := mkObject("key2", 2000)
	o3 := mkObject("key3", 3000)
	table.Update(o1.key, unsafe.Pointer(o1))
	table.Update(o2.key, unsafe.Pointer(o2))
	table.Update(o3.key, unsafe.Pointer(o3))

	if table.Remove(o1.key) != true {
		t.Errorf("Expected successful remove")
	}

	ro1 := (*object)(table.Get(o1.key))
	ro2 := (*object)(table.Get(o2.key))
	ro3 := (*object)(table.Get(o3.key))

	if ro1 != nil {
		t.Errorf("Expected not found")
	}

	if ro2 != o2 || ro3 != o3 {
		t.Errorf("Expected to find those objects")
	}
}

func TestDeleteSlowHT1(t *testing.T) {
	table := New(mkHashFun(100), equalObject)
	o1 := mkObject("key1", 1000)
	o2 := mkObject("key2", 2000)
	o3 := mkObject("key3", 3000)
	table.Update(o1.key, unsafe.Pointer(o1))
	table.Update(o2.key, unsafe.Pointer(o2))
	table.Update(o3.key, unsafe.Pointer(o3))

	if table.Remove(o2.key) != true {
		t.Errorf("Expected successful remove")
	}

	ro1 := (*object)(table.Get(o1.key))
	ro2 := (*object)(table.Get(o2.key))
	ro3 := (*object)(table.Get(o3.key))

	if ro2 == nil {
		t.Errorf("Expected not found")
	}

	if ro1 != o1 || ro3 != o3 {
		t.Errorf("Expected to find those objects")
	}
}

func TestSimple(t *testing.T) {
	table := New(crc32.ChecksumIEEE, equalObject)
	o1 := mkObject("key1", 100)
	o2 := mkObject("key1", 200)
	updated, old := table.Update(o1.key, unsafe.Pointer(o1))
	if updated == true || old != nil {
		t.Errorf("Expected update=false, old=nil")
	}

	updated, old = table.Update(o2.key, unsafe.Pointer(o2))
	if updated == false || old == nil {
	}

	o3 := table.Get(o1.key)
	if o3 == nil {
		t.Errorf("Expected non nil")
	} else {
		o4 := (*object)(o3)
		if o4.value != 200 {
			t.Errorf("Expected value = 200")
		}
	}
}
<commit_msg>nodetable: Add test to verify conflict bit during empty slowHT<commit_after>package nodetable

import "testing"
import "bytes"
import "hash/crc32"
import "unsafe"

type object struct {
	key   []byte
	value int
}

func equalObject(p unsafe.Pointer, k []byte) bool {
	obj := (*object)(p)
	return bytes.Equal(obj.key, k)
}

func mkHashFun(h uint32) HashFn {
	return func([]byte) uint32 {
		return h
	}
}

func mkObject(key string, v int) *object {
	return &object{
		key:   []byte(key),
		value: v,
	}
}

func TestPointerEncode(t *testing.T) {
	o1 := unsafe.Pointer(mkObject("key", 1000))
	v := encodePointer(o1, true)
	o2 := decodePointer(v)

	if o1 != o2 {
		t.Errorf("Expected encoded value to remain the same with conflict %p!=%p", o1, o2)
	}

	v = encodePointer(o1, false)
	o2 = decodePointer(v)

	if o1 != o2 {
		t.Errorf("Expected encoded value to remain the same without conflict %p!=%p", o1, o2)
	}
}

func TestInsertFastHT(t *testing.T) {
	table := New(mkHashFun(100), equalObject)
	o1 := mkObject("key", 1000)
	table.Update(o1.key, unsafe.Pointer(o1))
	o2 := (*object)(table.Get(o1.key))
	if o2 != o1 {
		t.Errorf("Expected same object")
	}
}

func TestInsertSlowHT(t *testing.T) {
	table := New(mkHashFun(100), equalObject)
	o1 := mkObject("key1", 1000)
	o2 := mkObject("key2", 2000)
	o3 := mkObject("key3", 3000)
	table.Update(o1.key, unsafe.Pointer(o1))
	table.Update(o2.key, unsafe.Pointer(o2))
	table.Update(o3.key, unsafe.Pointer(o3))
	ro1 := (*object)(table.Get(o1.key))
	ro2 := (*object)(table.Get(o2.key))
	ro3 := (*object)(table.Get(o3.key))
	if o1 != ro1 || o2 != ro2 || o3 != ro3 {
		t.Errorf("Expected same objects %p!=%p, %p!=%p, %p!=%p", o1, ro1, o2, ro2, o3, ro3)
	}
}

func TestUpdateFastHT(t *testing.T) {
	table := New(mkHashFun(100), equalObject)
	o1 := mkObject("key", 1000)
	o2 := mkObject("key", 2000)
	updated, old := table.Update(o1.key, unsafe.Pointer(o1))
	if updated != false || old != nil {
		t.Errorf("Expected successful insert")
	}

	updated, old = table.Update(o2.key, unsafe.Pointer(o2))
	if updated != true || (*object)(old) != o1 {
		t.Errorf("Expected old object to be returned")
	}
}

func TestUpdateSlowHT(t *testing.T) {
	table := New(mkHashFun(100), equalObject)
	o1 := mkObject("key0", 1000)
	o2 := mkObject("key1", 2000)
	o3 := mkObject("key1", 6000)
	updated, old := table.Update(o1.key, unsafe.Pointer(o1))
	if updated != false || old != nil {
		t.Errorf("Expected successful insert")
	}

	table.Update(o2.key, unsafe.Pointer(o2))
	updated, old = table.Update(o3.key, unsafe.Pointer(o3))
	if updated != true || (*object)(old) != o2 {
		t.Errorf("Expected old object to be returned")
	}
}

func TestDeleteFastHT1(t *testing.T) {
	table := New(mkHashFun(100), equalObject)
	o1 := mkObject("key", 1000)
	table.Update(o1.key, unsafe.Pointer(o1))
	o2 := (*object)(table.Get(o1.key))
	if o2 != o1 {
		t.Errorf("Expected same object")
	}

	if table.Remove(o1.key) != true {
		t.Errorf("Expected successful remove")
	}

	o3 := (*object)(table.Get(o1.key))
	if o3 != nil {
		t.Errorf("Expected not-found")
	}

	if table.Remove(o1.key) == true {
		t.Errorf("Expected remove fail")
	}
}

func TestDeleteFastHT2(t *testing.T) {
	table := New(mkHashFun(100), equalObject)
	o1 := mkObject("key1", 1000)
	o2 := mkObject("key2", 2000)
	o3 := mkObject("key3", 3000)
	table.Update(o1.key, unsafe.Pointer(o1))
	table.Update(o2.key, unsafe.Pointer(o2))
	table.Update(o3.key, unsafe.Pointer(o3))

	if table.Remove(o1.key) != true {
		t.Errorf("Expected successful remove")
	}

	ro1 := (*object)(table.Get(o1.key))
	ro2 := (*object)(table.Get(o2.key))
	ro3 := (*object)(table.Get(o3.key))

	if ro1 != nil {
		t.Errorf("Expected not found")
	}

	if ro2 != o2 || ro3 != o3 {
		t.Errorf("Expected to find those objects")
	}
}

func TestDeleteSlowHT1(t *testing.T) {
	table := New(mkHashFun(100), equalObject)
	o1 := mkObject("key1", 1000)
	o2 := mkObject("key2", 2000)
	o3 := mkObject("key3", 3000)
	table.Update(o1.key, unsafe.Pointer(o1))
	table.Update(o2.key, unsafe.Pointer(o2))
	table.Update(o3.key, unsafe.Pointer(o3))

	if table.Remove(o2.key) != true {
		t.Errorf("Expected successful remove")
	}

	ro1 := (*object)(table.Get(o1.key))
	ro2 := (*object)(table.Get(o2.key))
	ro3 := (*object)(table.Get(o3.key))

	if ro2 == nil {
		t.Errorf("Expected not found")
	}

	if ro1 != o1 || ro3 != o3 {
		t.Errorf("Expected to find those objects")
	}
}

func TestDeleteFastHT3(t *testing.T) {
	table := New(mkHashFun(100), equalObject)
	o1 := mkObject("key1", 1000)
	o2 := mkObject("key2", 2000)
	table.Update(o1.key, unsafe.Pointer(o1))
	table.Update(o2.key, unsafe.Pointer(o2))

	res := table.find(o1.key)
	if !table.hasConflict(res.fastHTValue) {
		t.Errorf("Expected conflict")
	}

	if table.Remove(o2.key) != true {
		t.Errorf("Expected successful remove")
	}

	ro1 := (*object)(table.Get(o1.key))
	ro2 := (*object)(table.Get(o2.key))

	if ro2 != nil {
		t.Errorf("Expected not found")
	}

	if ro1 != o1 {
		t.Errorf("Expected found")
	}

	res = table.find(o1.key)
	if table.hasConflict(res.fastHTValue) {
		t.Errorf("Expected no conflict")
	}

}

func TestSimple(t *testing.T) {
	table := New(crc32.ChecksumIEEE, equalObject)
	o1 := mkObject("key1", 100)
	o2 := mkObject("key1", 200)
	updated, old := table.Update(o1.key, unsafe.Pointer(o1))
	if updated == true || old != nil {
		t.Errorf("Expected update=false, old=nil")
	}

	updated, old = table.Update(o2.key, unsafe.Pointer(o2))
	if updated == false || old == nil {
	}

	o3 := table.Get(o1.key)
	if o3 == nil {
		t.Errorf("Expected non nil")
	} else {
		o4 := (*object)(o3)
		if o4.value != 200 {
			t.Errorf("Expected value = 200")
		}
	}
}
<|endoftext|>


<commit_before>/*
Copyright 2017 The Kubernetes Authors.

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

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

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

package features

import (
	"fmt"
	"sort"
	"strconv"
	"strings"

	"github.com/pkg/errors"
	"k8s.io/apimachinery/pkg/util/version"
	"k8s.io/component-base/featuregate"
)

const (

	// CoreDNS is GA in v1.11
	CoreDNS = "CoreDNS"
)

var coreDNSMessage = "featureGates:CoreDNS has been removed in v1.13\n" +
	"\tUse kubeadm-config to select which DNS addon to install."

// InitFeatureGates are the default feature gates for the init command
var InitFeatureGates = FeatureList{
	CoreDNS: {FeatureSpec: featuregate.FeatureSpec{Default: true, PreRelease: featuregate.Deprecated}, HiddenInHelpText: true, DeprecationMessage: coreDNSMessage},
}

// Feature represents a feature being gated
type Feature struct {
	featuregate.FeatureSpec
	MinimumVersion     *version.Version
	HiddenInHelpText   bool
	DeprecationMessage string
}

// FeatureList represents a list of feature gates
type FeatureList map[string]Feature

// ValidateVersion ensures that a feature gate list is compatible with the chosen Kubernetes version
func ValidateVersion(allFeatures FeatureList, requestedFeatures map[string]bool, requestedVersion string) error {
	if requestedVersion == "" {
		return nil
	}
	parsedExpVersion, err := version.ParseSemantic(requestedVersion)
	if err != nil {
		return errors.Wrapf(err, "error parsing version %s", requestedVersion)
	}
	for k := range requestedFeatures {
		if minVersion := allFeatures[k].MinimumVersion; minVersion != nil {
			if !parsedExpVersion.AtLeast(minVersion) {
				return errors.Errorf(
					"the requested Kubernetes version (%s) is incompatible with the %s feature gate, which needs %s as a minimum",
					requestedVersion, k, minVersion)
			}
		}
	}
	return nil
}

// Enabled indicates whether a feature name has been enabled
func Enabled(featureList map[string]bool, featureName string) bool {
	if enabled, ok := featureList[string(featureName)]; ok {
		return enabled
	}
	return InitFeatureGates[string(featureName)].Default
}

// Supports indicates whether a feature name is supported on the given
// feature set
func Supports(featureList FeatureList, featureName string) bool {
	for k, v := range featureList {
		if featureName == string(k) {
			return v.PreRelease != featuregate.Deprecated
		}
	}
	return false
}

// Keys returns a slice of feature names for a given feature set
func Keys(featureList FeatureList) []string {
	var list []string
	for k := range featureList {
		list = append(list, string(k))
	}
	return list
}

// KnownFeatures returns a slice of strings describing the FeatureList features.
func KnownFeatures(f *FeatureList) []string {
	var known []string
	for k, v := range *f {
		if v.HiddenInHelpText {
			continue
		}

		pre := ""
		if v.PreRelease != featuregate.GA {
			pre = fmt.Sprintf("%s - ", v.PreRelease)
		}
		known = append(known, fmt.Sprintf("%s=true|false (%sdefault=%t)", k, pre, v.Default))
	}
	sort.Strings(known)
	return known
}

// NewFeatureGate parses a string of the form "key1=value1,key2=value2,..." into a
// map[string]bool of known keys or returns an error.
func NewFeatureGate(f *FeatureList, value string) (map[string]bool, error) {
	featureGate := map[string]bool{}
	for _, s := range strings.Split(value, ",") {
		if len(s) == 0 {
			continue
		}

		arr := strings.SplitN(s, "=", 2)
		if len(arr) != 2 {
			return nil, errors.Errorf("missing bool value for feature-gate key:%s", s)
		}

		k := strings.TrimSpace(arr[0])
		v := strings.TrimSpace(arr[1])

		featureSpec, ok := (*f)[k]
		if !ok {
			return nil, errors.Errorf("unrecognized feature-gate key: %s", k)
		}

		if featureSpec.PreRelease == featuregate.Deprecated {
			return nil, errors.Errorf("feature-gate key is deprecated: %s", k)
		}

		boolValue, err := strconv.ParseBool(v)
		if err != nil {
			return nil, errors.Errorf("invalid value %v for feature-gate key: %s, use true|false instead", v, k)
		}
		featureGate[k] = boolValue
	}

	return featureGate, nil
}

// CheckDeprecatedFlags takes a list of existing feature gate flags and validates against the current feature flag set.
// It used during upgrades for ensuring consistency of feature gates used in an existing cluster, that might
// be created with a previous version of kubeadm, with the set of features currently supported by kubeadm
func CheckDeprecatedFlags(f *FeatureList, features map[string]bool) map[string]string {
	deprecatedMsg := map[string]string{}
	for k := range features {
		featureSpec, ok := (*f)[k]
		if !ok {
			// This case should never happen, it is implemented only as a sentinel
			// for removal of flags executed when flags are still in use (always before deprecate, then after one cycle remove)
			deprecatedMsg[k] = fmt.Sprintf("Unknown feature gate flag: %s", k)
		}

		if featureSpec.PreRelease == featuregate.Deprecated {
			if _, ok := deprecatedMsg[k]; !ok {
				deprecatedMsg[k] = featureSpec.DeprecationMessage
			}
		}
	}

	return deprecatedMsg
}
<commit_msg>Adds kubeadm feature-gate for dual-stack (IPv6DualStack). Issue: #1612<commit_after>/*
Copyright 2017 The Kubernetes Authors.

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

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

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

package features

import (
	"fmt"
	"sort"
	"strconv"
	"strings"

	"github.com/pkg/errors"
	"k8s.io/apimachinery/pkg/util/version"
	"k8s.io/component-base/featuregate"
)

const (

	// CoreDNS is GA in v1.11
	CoreDNS = "CoreDNS"
	// IPv6DualStack is expected to be alpha in v1.16
	IPv6DualStack = "IPv6DualStack"
)

var coreDNSMessage = "featureGates:CoreDNS has been removed in v1.13\n" +
	"\tUse kubeadm-config to select which DNS addon to install."

// InitFeatureGates are the default feature gates for the init command
var InitFeatureGates = FeatureList{
	CoreDNS:       {FeatureSpec: featuregate.FeatureSpec{Default: true, PreRelease: featuregate.Deprecated}, HiddenInHelpText: true, DeprecationMessage: coreDNSMessage},
	IPv6DualStack: {FeatureSpec: featuregate.FeatureSpec{Default: false, PreRelease: featuregate.Alpha}},
}

// Feature represents a feature being gated
type Feature struct {
	featuregate.FeatureSpec
	MinimumVersion     *version.Version
	HiddenInHelpText   bool
	DeprecationMessage string
}

// FeatureList represents a list of feature gates
type FeatureList map[string]Feature

// ValidateVersion ensures that a feature gate list is compatible with the chosen Kubernetes version
func ValidateVersion(allFeatures FeatureList, requestedFeatures map[string]bool, requestedVersion string) error {
	if requestedVersion == "" {
		return nil
	}
	parsedExpVersion, err := version.ParseSemantic(requestedVersion)
	if err != nil {
		return errors.Wrapf(err, "error parsing version %s", requestedVersion)
	}
	for k := range requestedFeatures {
		if minVersion := allFeatures[k].MinimumVersion; minVersion != nil {
			if !parsedExpVersion.AtLeast(minVersion) {
				return errors.Errorf(
					"the requested Kubernetes version (%s) is incompatible with the %s feature gate, which needs %s as a minimum",
					requestedVersion, k, minVersion)
			}
		}
	}
	return nil
}

// Enabled indicates whether a feature name has been enabled
func Enabled(featureList map[string]bool, featureName string) bool {
	if enabled, ok := featureList[string(featureName)]; ok {
		return enabled
	}
	return InitFeatureGates[string(featureName)].Default
}

// Supports indicates whether a feature name is supported on the given
// feature set
func Supports(featureList FeatureList, featureName string) bool {
	for k, v := range featureList {
		if featureName == string(k) {
			return v.PreRelease != featuregate.Deprecated
		}
	}
	return false
}

// Keys returns a slice of feature names for a given feature set
func Keys(featureList FeatureList) []string {
	var list []string
	for k := range featureList {
		list = append(list, string(k))
	}
	return list
}

// KnownFeatures returns a slice of strings describing the FeatureList features.
func KnownFeatures(f *FeatureList) []string {
	var known []string
	for k, v := range *f {
		if v.HiddenInHelpText {
			continue
		}

		pre := ""
		if v.PreRelease != featuregate.GA {
			pre = fmt.Sprintf("%s - ", v.PreRelease)
		}
		known = append(known, fmt.Sprintf("%s=true|false (%sdefault=%t)", k, pre, v.Default))
	}
	sort.Strings(known)
	return known
}

// NewFeatureGate parses a string of the form "key1=value1,key2=value2,..." into a
// map[string]bool of known keys or returns an error.
func NewFeatureGate(f *FeatureList, value string) (map[string]bool, error) {
	featureGate := map[string]bool{}
	for _, s := range strings.Split(value, ",") {
		if len(s) == 0 {
			continue
		}

		arr := strings.SplitN(s, "=", 2)
		if len(arr) != 2 {
			return nil, errors.Errorf("missing bool value for feature-gate key:%s", s)
		}

		k := strings.TrimSpace(arr[0])
		v := strings.TrimSpace(arr[1])

		featureSpec, ok := (*f)[k]
		if !ok {
			return nil, errors.Errorf("unrecognized feature-gate key: %s", k)
		}

		if featureSpec.PreRelease == featuregate.Deprecated {
			return nil, errors.Errorf("feature-gate key is deprecated: %s", k)
		}

		boolValue, err := strconv.ParseBool(v)
		if err != nil {
			return nil, errors.Errorf("invalid value %v for feature-gate key: %s, use true|false instead", v, k)
		}
		featureGate[k] = boolValue
	}

	return featureGate, nil
}

// CheckDeprecatedFlags takes a list of existing feature gate flags and validates against the current feature flag set.
// It used during upgrades for ensuring consistency of feature gates used in an existing cluster, that might
// be created with a previous version of kubeadm, with the set of features currently supported by kubeadm
func CheckDeprecatedFlags(f *FeatureList, features map[string]bool) map[string]string {
	deprecatedMsg := map[string]string{}
	for k := range features {
		featureSpec, ok := (*f)[k]
		if !ok {
			// This case should never happen, it is implemented only as a sentinel
			// for removal of flags executed when flags are still in use (always before deprecate, then after one cycle remove)
			deprecatedMsg[k] = fmt.Sprintf("Unknown feature gate flag: %s", k)
		}

		if featureSpec.PreRelease == featuregate.Deprecated {
			if _, ok := deprecatedMsg[k]; !ok {
				deprecatedMsg[k] = featureSpec.DeprecationMessage
			}
		}
	}

	return deprecatedMsg
}
<|endoftext|>


<commit_before>package mycolor

import (
	"math"
	"math/rand"
)

// The random number generator
var RNG *rand.Rand

func init() {
	RNG = rand.New(rand.NewSource(99))
}

//================================================================================
// COLOR

type MyColor struct {
	R         uint8
	G         uint8
	B         uint8
	A         uint8
	H         float64
	S         float64
	V         float64
	SortValue float64
}

// Compute and set the SortValue for the MyColor object.
// "kind" is the type of sort to do.  Use one of: random semirandom h h2 v s
func (c *MyColor) SetSortValue(kind string, ii int) {
	switch kind {
	case "random":
		// totally randomize the order of the pixels
		c.SortValue = RNG.Float64()
	case "semirandom":
		// move pixels plus or minus 100 pixels
		c.SortValue = float64(ii)/4 + RNG.Float64()*25
	case "h":
		c.SortValue = c.H
	case "h2":
		// sort by hue unless saturation is too low.
		// unsaturated pixels will sort to the front.
		c.SortValue = c.H + 0.15
		if c.SortValue > 1 {
			c.SortValue -= 1
		}
		if c.S < 0.07 {
			c.SortValue -= 900
		}
	case "v":
		c.SortValue = -(float64(c.R)/255*0.30 + float64(c.G)/255*0.59 + float64(c.B)/255*0.11)
	case "s":
		c.SortValue = c.S
	default:
		panic("bad sort kind: " + kind)
	}
}

// Read r, g b in the range 0-255; set h, s, v in the range 0-1.
// Taken from http://stackoverflow.com/questions/8022885/rgb-to-hsv-color-in-javascript
func (c *MyColor) ComputeHSV() {
	var h, s, v float64

	r := float64(c.R) / 255
	g := float64(c.G) / 255
	b := float64(c.B) / 255

	v = math.Max(r, math.Max(g, b))
	diff := v - math.Min(r, math.Min(g, b))

	if diff == 0 {
		h = 0
		s = 0
	} else {
		s = diff / v
		rr := (v-r)/6.0/diff + 0.5
		gg := (v-g)/6.0/diff + 0.5
		bb := (v-b)/6.0/diff + 0.5
		if r == v {
			h = bb - gg
		} else if g == v {
			h = 1.0/3.0 + rr - bb
		} else if b == v {
			h = 2.0/3.0 + gg - rr
		}

		if h < 0 {
			h += 1
		} else if h > 1 {
			h -= 1
		}
	}
	c.H = h
	c.S = s
	c.V = v
}
<commit_msg>Change mycolor to use float32 instead of float64 for better speed and memory usage<commit_after>package mycolor

import (
	"math/rand"
)

// The random number generator
var RNG *rand.Rand

func init() {
	RNG = rand.New(rand.NewSource(99))
}

//================================================================================
// COLOR

type MyColor struct {
	R         uint8
	G         uint8
	B         uint8
	A         uint8
	H         float32
	S         float32
	V         float32
	SortValue float32
}

// Compute and set the SortValue for the MyColor object.
// "kind" is the type of sort to do.  Use one of: random semirandom h h2 v s
func (c *MyColor) SetSortValue(kind string, ii int) {
	switch kind {
	case "random":
		// totally randomize the order of the pixels
		c.SortValue = RNG.Float32()
	case "semirandom":
		// move pixels plus or minus 100 pixels
		c.SortValue = float32(ii)/4 + RNG.Float32()*25
	case "h":
		c.SortValue = c.H
	case "h2":
		// sort by hue unless saturation is too low.
		// unsaturated pixels will sort to the front.
		c.SortValue = c.H + 0.15
		if c.SortValue > 1 {
			c.SortValue -= 1
		}
		if c.S < 0.07 {
			c.SortValue -= 900
		}
	case "v":
		c.SortValue = -(float32(c.R)/255*0.30 + float32(c.G)/255*0.59 + float32(c.B)/255*0.11)
	case "s":
		c.SortValue = c.S
	default:
		panic("bad sort kind: " + kind)
	}
}

func threeMax(a float32, b float32, c float32) float32 {
	if a > b {
		if a > c {
			return a
		} else {
			return c
		}
	} else {
		if b > c {
			return b
		} else {
			return c
		}
	}
}

func threeMin(a float32, b float32, c float32) float32 {
	if a < b {
		if a < c {
			return a
		} else {
			return c
		}
	} else {
		if b < c {
			return b
		} else {
			return c
		}
	}
}

// Read r, g b in the range 0-255; set h, s, v in the range 0-1.
// Taken from http://stackoverflow.com/questions/8022885/rgb-to-hsv-color-in-javascript
func (c *MyColor) ComputeHSV() {
	var h, s, v float32

	r := float32(c.R) / 255
	g := float32(c.G) / 255
	b := float32(c.B) / 255

	v = threeMax(r, g, b)
	diff := v - threeMin(r, g, b)

	if diff == 0 {
		h = 0
		s = 0
	} else {
		s = diff / v
		rr := (v-r)/6.0/diff + 0.5
		gg := (v-g)/6.0/diff + 0.5
		bb := (v-b)/6.0/diff + 0.5
		if r == v {
			h = bb - gg
		} else if g == v {
			h = 1.0/3.0 + rr - bb
		} else if b == v {
			h = 2.0/3.0 + gg - rr
		}

		if h < 0 {
			h += 1
		} else if h > 1 {
			h -= 1
		}
	}
	c.H = h
	c.S = s
	c.V = v
}
<|endoftext|>


<commit_before>// Package handler is the handler collection of the logger.
package handler

import (
	"errors"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"regexp"
	"sort"
	"sync"
	"time"

	"github.com/xgfone/go-tools/file"
	"github.com/xgfone/go-tools/function"
)

const (
	// FileMode is the mode to open the log file.
	FileMode = os.O_APPEND | os.O_CREATE | os.O_WRONLY

	// FilePerm is the default permission to open the log file.
	FilePerm os.FileMode = 0644
)

var (
	dayRE       = regexp.MustCompile(`^\d{4}-\d{2}-\d{2}(\.\w+)?$`)
	day   int64 = 3600 * 24

	time2fmt = map[int64]string{
		day: "2006-01-02",
	}

	filePerm = FilePerm
)

var (
	// ErrFileNotOpen is the error to open the log file.
	ErrFileNotOpen = errors.New("The file is not opened")
)

// ResetDefaultFilePerm resets the default permission to open the log file.
func ResetDefaultFilePerm(perm int) {
	filePerm = os.FileMode(perm)
}

// TimedRotatingFile is a file handler based on the timed rotating, like
// `logging.handlers.TimedRotatingFileHandler` in Python.
// Now only support the rotation by day.
type TimedRotatingFile struct {
	sync.Mutex
	w io.WriteCloser

	filename    string
	backupCount int
	interval    int64
	when        int64
	rotatorAt   int64
	extRE       *regexp.Regexp
}

// NewTimedRotatingFile creates a new TimedRotatingFile.
//
// If failed, it will panic.
func NewTimedRotatingFile(filename string, count int) *TimedRotatingFile {
	filename = file.Abs(filename)
	t := TimedRotatingFile{
		filename:    filename,
		when:        day,
		extRE:       dayRE,
		backupCount: count,
		interval:    day,
	}
	t.reComputeRollover()
	if err := t.open(); err != nil {
		panic(err)
	}
	return &t
}

// WriteString writes the string data into the file, which may rotate the file if necessary.
func (t *TimedRotatingFile) WriteString(data string) (n int, err error) {
	return t.Write([]byte(data))
}

// Write writes the byte slice data into the file, which may rotate the file if necessary.
func (t *TimedRotatingFile) Write(data []byte) (n int, err error) {
	t.Lock()
	defer t.Unlock()

	if t.w == nil {
		err = ErrFileNotOpen
		return
	}

	if t.shouldRollover() {
		if err = t.doRollover(); err != nil {
			return
		}
	}

	return t.w.Write(data)
}

func (t *TimedRotatingFile) shouldRollover() bool {
	return time.Now().Unix() >= t.rotatorAt
}

// Close closes the handler.
// Return ErrFileNotOpen when to write the data to the handler after closed.
func (t *TimedRotatingFile) Close() (err error) {
	if err = t.w.Close(); err != nil {
		return
	}
	t.w = nil
	return
}

func (t *TimedRotatingFile) open() error {
	file, err := os.OpenFile(t.filename, FileMode, FilePerm)
	if err != nil {
		return err
	}
	t.w = file
	return nil
}

func (t *TimedRotatingFile) doRollover() (err error) {
	if err = t.Close(); err != nil {
		return
	}

	dstTime := t.rotatorAt - t.interval
	dstPath := t.filename + "." + time.Unix(dstTime, 0).Format(time2fmt[t.when])
	if file.IsExist(dstPath) {
		os.Remove(dstPath)
	}

	if file.IsFile(t.filename) {
		if err = os.Rename(t.filename, dstPath); err != nil {
			return err
		}
	}

	if t.backupCount > 0 {
		for _, file := range t.getFilesToDelete() {
			os.Remove(file)
		}
	}

	t.reComputeRollover()
	return t.open()
}

func (t *TimedRotatingFile) getFilesToDelete() []string {
	result := make([]string, 0, 30)
	dirName, baseName := filepath.Split(t.filename)
	fileNames, err := file.ListDir2(dirName)
	if err != nil {
		return result
	}

	var suffix, prefix string
	_prefix := baseName + "."
	plen := len(_prefix)
	for _, fileName := range fileNames {
		if len(fileName) <= plen {
			continue
		}
		prefix = string(fileName[:plen])
		if _prefix == prefix {
			suffix = string(fileName[plen:])
			if t.extRE.MatchString(suffix) {
				result = append(result, filepath.Join(dirName, fileName))
			}
		}
	}

	if len(result) <= t.backupCount {
		return []string{}
	}
	sort.Strings(result)
	return result[:len(result)-t.backupCount]
}

func (t *TimedRotatingFile) reComputeRollover() {
	currentTime := time.Now().Unix()

	_time := time.Unix(currentTime, 0)
	currentHour := _time.Hour()
	currentMinute := _time.Minute()
	currentSecond := _time.Second()

	r := t.interval - int64((currentHour*60+currentMinute)*60+currentSecond)
	t.rotatorAt = currentTime + r
}

// SizedRotatingFile is a rotating logging handler based on the size.
type SizedRotatingFile struct {
	sync.Mutex
	w *WriteCloser

	filename    string
	maxSize     int
	backupCount int
	nbytes      int
}

// NewSizedRotatingFile returns a new RotatingFile.
func NewSizedRotatingFile(filename string, size, count int) *SizedRotatingFile {
	r := &SizedRotatingFile{
		filename:    filename,
		maxSize:     size,
		backupCount: count,
	}

	if err := r.open(); err != nil {
		panic(err)
	}
	return r
}

// Write implements the interface io.Writer.
func (r *SizedRotatingFile) Write(data []byte) (n int, err error) {
	r.Lock()
	defer r.Unlock()

	if r.w == nil || r.w.Closed() {
		err = ErrFileNotOpen
		return
	}

	if r.nbytes+len(data) > r.maxSize {
		if err = r.doRollover(); err != nil {
			return
		}
	}

	if n, err = r.w.Write(data); err != nil {
		return
	}
	r.nbytes += n
	return
}

// WriteString writes the string.
func (r *SizedRotatingFile) WriteString(data string) (n int, err error) {
	return r.Write([]byte(data))
}

// Close implements the interface io.Closer.
func (r *SizedRotatingFile) Close() (err error) {
	r.Lock()
	err = r.close()
	r.Unlock()
	return
}

// Flush flushes the log cache into the file.
func (r *SizedRotatingFile) Flush() (err error) {
	r.Lock()
	err = r.w.Flush()
	r.Unlock()
	return
}

// ReOpen reopens the log file.
//
// Notice: If it failed to reopen the log file, the log will be redirected to
// os.Stderr.
func (r *SizedRotatingFile) ReOpen() (err error) {
	r.Lock()
	r.close()
	err = r.open()
	r.Unlock()
	return
}

func (r *SizedRotatingFile) close() (err error) {
	if r.w != nil {
		err = r.w.Close()
		r.w = nil
	}
	return
}

func (r *SizedRotatingFile) doRollover() (err error) {
	if r.backupCount > 0 {
		if err = r.close(); err != nil {
			return
		}
		for _, i := range function.Range(r.backupCount-1, 0, -1) {
			sfn := fmt.Sprintf("%s.%d", r.filename, i)
			dfn := fmt.Sprintf("%s.%d", r.filename, i+1)
			if file.IsExist(sfn) {
				if file.IsExist(dfn) {
					os.Remove(dfn)
				}
				if err = os.Rename(sfn, dfn); err != nil {
					return
				}
			}
		}
		dfn := r.filename + ".1"
		if file.IsExist(dfn) {
			if err = os.Remove(dfn); err != nil {
				return
			}
		}
		if file.IsExist(r.filename) {
			if err = os.Rename(r.filename, dfn); err != nil {
				return
			}
		}
		err = r.open()
	}
	return
}

func (r *SizedRotatingFile) open() (err error) {
	file, err := os.OpenFile(r.filename, FileMode, FilePerm)
	if err != nil {
		return
	}
	info, err := file.Stat()
	if err != nil {
		return
	}
	r.nbytes = int(info.Size())
	r.w = NewWriteCloser(file)
	return
}
<commit_msg>Deprecate TimeRotatingFile<commit_after>// Package handler is the handler collection of the logger.
package handler

import (
	"errors"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"regexp"
	"sort"
	"sync"
	"time"

	"github.com/xgfone/go-tools/file"
	"github.com/xgfone/go-tools/function"
)

const (
	// FileMode is the mode to open the log file.
	FileMode = os.O_APPEND | os.O_CREATE | os.O_WRONLY

	// FilePerm is the default permission to open the log file.
	FilePerm os.FileMode = 0644
)

var (
	dayRE       = regexp.MustCompile(`^\d{4}-\d{2}-\d{2}(\.\w+)?$`)
	day   int64 = 3600 * 24

	time2fmt = map[int64]string{
		day: "2006-01-02",
	}

	filePerm = FilePerm
)

var (
	// ErrFileNotOpen is the error to open the log file.
	ErrFileNotOpen = errors.New("The file is not opened")
)

// ResetDefaultFilePerm resets the default permission to open the log file.
func ResetDefaultFilePerm(perm int) {
	filePerm = os.FileMode(perm)
}

// TimedRotatingFile is a file handler based on the timed rotating, like
// `logging.handlers.TimedRotatingFileHandler` in Python.
// Now only support the rotation by day.
//
// DEPRECATED!!! Not suggest to use it again. Use SizedRotatingFile instead.
type TimedRotatingFile struct {
	sync.Mutex
	w io.WriteCloser

	filename    string
	backupCount int
	interval    int64
	when        int64
	rotatorAt   int64
	extRE       *regexp.Regexp
}

// NewTimedRotatingFile creates a new TimedRotatingFile.
//
// If failed, it will panic.
func NewTimedRotatingFile(filename string, count int) *TimedRotatingFile {
	filename = file.Abs(filename)
	t := TimedRotatingFile{
		filename:    filename,
		when:        day,
		extRE:       dayRE,
		backupCount: count,
		interval:    day,
	}
	t.reComputeRollover()
	if err := t.open(); err != nil {
		panic(err)
	}
	return &t
}

// WriteString writes the string data into the file, which may rotate the file if necessary.
func (t *TimedRotatingFile) WriteString(data string) (n int, err error) {
	return t.Write([]byte(data))
}

// Write writes the byte slice data into the file, which may rotate the file if necessary.
func (t *TimedRotatingFile) Write(data []byte) (n int, err error) {
	t.Lock()
	defer t.Unlock()

	if t.w == nil {
		err = ErrFileNotOpen
		return
	}

	if t.shouldRollover() {
		if err = t.doRollover(); err != nil {
			return
		}
	}

	return t.w.Write(data)
}

func (t *TimedRotatingFile) shouldRollover() bool {
	return time.Now().Unix() >= t.rotatorAt
}

// Close closes the handler.
// Return ErrFileNotOpen when to write the data to the handler after closed.
func (t *TimedRotatingFile) Close() (err error) {
	if err = t.w.Close(); err != nil {
		return
	}
	t.w = nil
	return
}

func (t *TimedRotatingFile) open() error {
	file, err := os.OpenFile(t.filename, FileMode, FilePerm)
	if err != nil {
		return err
	}
	t.w = file
	return nil
}

func (t *TimedRotatingFile) doRollover() (err error) {
	if err = t.Close(); err != nil {
		return
	}

	dstTime := t.rotatorAt - t.interval
	dstPath := t.filename + "." + time.Unix(dstTime, 0).Format(time2fmt[t.when])
	if file.IsExist(dstPath) {
		os.Remove(dstPath)
	}

	if file.IsFile(t.filename) {
		if err = os.Rename(t.filename, dstPath); err != nil {
			return err
		}
	}

	if t.backupCount > 0 {
		for _, file := range t.getFilesToDelete() {
			os.Remove(file)
		}
	}

	t.reComputeRollover()
	return t.open()
}

func (t *TimedRotatingFile) getFilesToDelete() []string {
	result := make([]string, 0, 30)
	dirName, baseName := filepath.Split(t.filename)
	fileNames, err := file.ListDir2(dirName)
	if err != nil {
		return result
	}

	var suffix, prefix string
	_prefix := baseName + "."
	plen := len(_prefix)
	for _, fileName := range fileNames {
		if len(fileName) <= plen {
			continue
		}
		prefix = string(fileName[:plen])
		if _prefix == prefix {
			suffix = string(fileName[plen:])
			if t.extRE.MatchString(suffix) {
				result = append(result, filepath.Join(dirName, fileName))
			}
		}
	}

	if len(result) <= t.backupCount {
		return []string{}
	}
	sort.Strings(result)
	return result[:len(result)-t.backupCount]
}

func (t *TimedRotatingFile) reComputeRollover() {
	currentTime := time.Now().Unix()

	_time := time.Unix(currentTime, 0)
	currentHour := _time.Hour()
	currentMinute := _time.Minute()
	currentSecond := _time.Second()

	r := t.interval - int64((currentHour*60+currentMinute)*60+currentSecond)
	t.rotatorAt = currentTime + r
}

// SizedRotatingFile is a rotating logging handler based on the size.
type SizedRotatingFile struct {
	sync.Mutex
	w *WriteCloser

	filename    string
	maxSize     int
	backupCount int
	nbytes      int
}

// NewSizedRotatingFile returns a new RotatingFile.
func NewSizedRotatingFile(filename string, size, count int) *SizedRotatingFile {
	r := &SizedRotatingFile{
		filename:    filename,
		maxSize:     size,
		backupCount: count,
	}

	if err := r.open(); err != nil {
		panic(err)
	}
	return r
}

// Write implements the interface io.Writer.
func (r *SizedRotatingFile) Write(data []byte) (n int, err error) {
	r.Lock()
	defer r.Unlock()

	if r.w == nil || r.w.Closed() {
		err = ErrFileNotOpen
		return
	}

	if r.nbytes+len(data) > r.maxSize {
		if err = r.doRollover(); err != nil {
			return
		}
	}

	if n, err = r.w.Write(data); err != nil {
		return
	}
	r.nbytes += n
	return
}

// WriteString writes the string.
func (r *SizedRotatingFile) WriteString(data string) (n int, err error) {
	return r.Write([]byte(data))
}

// Close implements the interface io.Closer.
func (r *SizedRotatingFile) Close() (err error) {
	r.Lock()
	err = r.close()
	r.Unlock()
	return
}

// Flush flushes the log cache into the file.
func (r *SizedRotatingFile) Flush() (err error) {
	r.Lock()
	err = r.w.Flush()
	r.Unlock()
	return
}

// ReOpen reopens the log file.
//
// Notice: If it failed to reopen the log file, the log will be redirected to
// os.Stderr.
func (r *SizedRotatingFile) ReOpen() (err error) {
	r.Lock()
	r.close()
	err = r.open()
	r.Unlock()
	return
}

func (r *SizedRotatingFile) close() (err error) {
	if r.w != nil {
		err = r.w.Close()
		r.w = nil
	}
	return
}

func (r *SizedRotatingFile) doRollover() (err error) {
	if r.backupCount > 0 {
		if err = r.close(); err != nil {
			return
		}
		for _, i := range function.Range(r.backupCount-1, 0, -1) {
			sfn := fmt.Sprintf("%s.%d", r.filename, i)
			dfn := fmt.Sprintf("%s.%d", r.filename, i+1)
			if file.IsExist(sfn) {
				if file.IsExist(dfn) {
					os.Remove(dfn)
				}
				if err = os.Rename(sfn, dfn); err != nil {
					return
				}
			}
		}
		dfn := r.filename + ".1"
		if file.IsExist(dfn) {
			if err = os.Remove(dfn); err != nil {
				return
			}
		}
		if file.IsExist(r.filename) {
			if err = os.Rename(r.filename, dfn); err != nil {
				return
			}
		}
		err = r.open()
	}
	return
}

func (r *SizedRotatingFile) open() (err error) {
	file, err := os.OpenFile(r.filename, FileMode, FilePerm)
	if err != nil {
		return
	}
	info, err := file.Stat()
	if err != nil {
		return
	}
	r.nbytes = int(info.Size())
	r.w = NewWriteCloser(file)
	return
}
<|endoftext|>