<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"reflect"
	"strings"

	"github.com/gorilla/mux"
	_ "github.com/mattn/go-sqlite3"

	"github.com/lxc/lxd/shared"

	log "gopkg.in/inconshreveable/log15.v2"
)

/* This is used for both profiles post and profile put */
type profilesPostReq struct {
	Name        string            `json:"name"`
	Config      map[string]string `json:"config"`
	Description string            `json:"description"`
	Devices     shared.Devices    `json:"devices"`
}

func profilesGet(d *Daemon, r *http.Request) Response {
	results, err := dbProfiles(d.db)
	if err != nil {
		return SmartError(err)
	}

	recursion := d.isRecursionRequest(r)

	resultString := make([]string, len(results))
	resultMap := make([]*shared.ProfileConfig, len(results))
	i := 0
	for _, name := range results {
		if !recursion {
			url := fmt.Sprintf("/%s/profiles/%s", shared.APIVersion, name)
			resultString[i] = url
		} else {
			profile, err := doProfileGet(d, name)
			if err != nil {
				shared.Log.Error("Failed to get profile", log.Ctx{"profile": name})
				continue
			}
			resultMap[i] = profile
		}
		i++
	}

	if !recursion {
		return SyncResponse(true, resultString)
	}

	return SyncResponse(true, resultMap)
}

func profilesPost(d *Daemon, r *http.Request) Response {
	req := profilesPostReq{}
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		return BadRequest(err)
	}

	// Sanity checks
	if req.Name == "" {
		return BadRequest(fmt.Errorf("No name provided"))
	}

	_, profile, _ := dbProfileGet(d.db, req.Name)
	if profile != nil {
		return BadRequest(fmt.Errorf("The profile already exists"))
	}

	if strings.Contains(req.Name, "/") {
		return BadRequest(fmt.Errorf("Profile names may not contain slashes"))
	}

	if shared.StringInSlice(req.Name, []string{".", ".."}) {
		return BadRequest(fmt.Errorf("Invalid profile name '%s'", req.Name))
	}

	err := containerValidConfig(d, req.Config, true, false)
	if err != nil {
		return BadRequest(err)
	}

	err = containerValidDevices(req.Devices, true, false)
	if err != nil {
		return BadRequest(err)
	}

	// Update DB entry
	_, err = dbProfileCreate(d.db, req.Name, req.Description, req.Config, req.Devices)
	if err != nil {
		return InternalError(
			fmt.Errorf("Error inserting %s into database: %s", req.Name, err))
	}

	return SyncResponseLocation(true, nil, fmt.Sprintf("/%s/profiles/%s", shared.APIVersion, req.Name))
}

var profilesCmd = Command{
	name: "profiles",
	get:  profilesGet,
	post: profilesPost}

func doProfileGet(d *Daemon, name string) (*shared.ProfileConfig, error) {
	_, profile, err := dbProfileGet(d.db, name)
	return profile, err
}

func profileGet(d *Daemon, r *http.Request) Response {
	name := mux.Vars(r)["name"]

	resp, err := doProfileGet(d, name)
	if err != nil {
		return SmartError(err)
	}

	return SyncResponseETag(true, resp, resp)
}

func getRunningContainersWithProfile(d *Daemon, profile string) []container {
	results := []container{}

	output, err := dbProfileContainersGet(d.db, profile)
	if err != nil {
		return results
	}

	for _, name := range output {
		c, err := containerLoadByName(d, name)
		if err != nil {
			shared.Log.Error("Failed opening container", log.Ctx{"container": name})
			continue
		}
		results = append(results, c)
	}
	return results
}

func profilePut(d *Daemon, r *http.Request) Response {
	// Get the profile
	name := mux.Vars(r)["name"]
	id, profile, err := dbProfileGet(d.db, name)
	if err != nil {
		return InternalError(fmt.Errorf("Failed to retrieve profile='%s'", name))
	}

	// Validate the ETag
	err = etagCheck(r, profile)
	if err != nil {
		return PreconditionFailed(err)
	}

	req := profilesPostReq{}
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		return BadRequest(err)
	}

	return doProfileUpdate(d, name, id, profile, req)
}

func profilePatch(d *Daemon, r *http.Request) Response {
	// Get the profile
	name := mux.Vars(r)["name"]
	id, profile, err := dbProfileGet(d.db, name)
	if err != nil {
		return InternalError(fmt.Errorf("Failed to retrieve profile='%s'", name))
	}

	// Validate the ETag
	err = etagCheck(r, profile)
	if err != nil {
		return PreconditionFailed(err)
	}

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return InternalError(err)
	}

	rdr1 := ioutil.NopCloser(bytes.NewBuffer(body))
	rdr2 := ioutil.NopCloser(bytes.NewBuffer(body))

	reqRaw := shared.Jmap{}
	if err := json.NewDecoder(rdr1).Decode(&reqRaw); err != nil {
		return BadRequest(err)
	}

	req := profilesPostReq{}
	if err := json.NewDecoder(rdr2).Decode(&req); err != nil {
		return BadRequest(err)
	}

	// Get Description
	_, err = reqRaw.GetString("description")
	if err != nil {
		req.Description = profile.Description
	}

	// Get Config
	if req.Config == nil {
		req.Config = profile.Config
	} else {
		for k, v := range profile.Config {
			_, ok := req.Config[k]
			if !ok {
				req.Config[k] = v
			}
		}
	}

	// Get Devices
	if req.Devices == nil {
		req.Devices = profile.Devices
	} else {
		for k, v := range profile.Devices {
			_, ok := req.Devices[k]
			if !ok {
				req.Devices[k] = v
			}
		}
	}

	return doProfileUpdate(d, name, id, profile, req)
}

func doProfileUpdate(d *Daemon, name string, id int64, profile *shared.ProfileConfig, req profilesPostReq) Response {
	// Sanity checks
	err := containerValidConfig(d, req.Config, true, false)
	if err != nil {
		return BadRequest(err)
	}

	err = containerValidDevices(req.Devices, true, false)
	if err != nil {
		return BadRequest(err)
	}

	// Get the running container list
	clist := getRunningContainersWithProfile(d, name)
	var containers []container
	for _, c := range clist {
		if !c.IsRunning() {
			continue
		}

		containers = append(containers, c)
	}

	// Update the database
	tx, err := dbBegin(d.db)
	if err != nil {
		return InternalError(err)
	}

	if profile.Description != req.Description {
		err = dbProfileDescriptionUpdate(tx, id, req.Description)
		if err != nil {
			tx.Rollback()
			return InternalError(err)
		}
	}

	// Optimize for description-only changes
	if reflect.DeepEqual(profile.Config, req.Config) && reflect.DeepEqual(profile.Devices, req.Devices) {
		err = txCommit(tx)
		if err != nil {
			return InternalError(err)
		}

		return EmptySyncResponse
	}

	err = dbProfileConfigClear(tx, id)
	if err != nil {
		tx.Rollback()
		return InternalError(err)
	}

	err = dbProfileConfigAdd(tx, id, req.Config)
	if err != nil {
		tx.Rollback()
		return SmartError(err)
	}

	err = dbDevicesAdd(tx, "profile", id, req.Devices)
	if err != nil {
		tx.Rollback()
		return SmartError(err)
	}

	err = txCommit(tx)
	if err != nil {
		return InternalError(err)
	}

	// Update all the containers using the profile. Must be done after txCommit due to DB lock.
	failures := map[string]error{}
	for _, c := range containers {
		err = c.Update(containerArgs{
			Architecture: c.Architecture(),
			Ephemeral:    c.IsEphemeral(),
			Config:       c.LocalConfig(),
			Devices:      c.LocalDevices(),
			Profiles:     c.Profiles()}, true)

		if err != nil {
			failures[c.Name()] = err
		}
	}

	if len(failures) != 0 {
		msg := "The following containers failed to update (profile change still saved):\n"
		for cname, err := range failures {
			msg += fmt.Sprintf(" - %s: %s\n", cname, err)
		}
		return InternalError(fmt.Errorf("%s", msg))
	}

	return EmptySyncResponse
}

// The handler for the post operation.
func profilePost(d *Daemon, r *http.Request) Response {
	name := mux.Vars(r)["name"]

	req := profilesPostReq{}
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		return BadRequest(err)
	}

	// Sanity checks
	if req.Name == "" {
		return BadRequest(fmt.Errorf("No name provided"))
	}

	// Check that the name isn't already in use
	id, _, _ := dbProfileGet(d.db, req.Name)
	if id > 0 {
		return Conflict
	}

	if strings.Contains(req.Name, "/") {
		return BadRequest(fmt.Errorf("Profile names may not contain slashes"))
	}

	if shared.StringInSlice(req.Name, []string{".", ".."}) {
		return BadRequest(fmt.Errorf("Invalid profile name '%s'", req.Name))
	}

	err := dbProfileUpdate(d.db, name, req.Name)
	if err != nil {
		return InternalError(err)
	}

	return SyncResponseLocation(true, nil, fmt.Sprintf("/%s/profiles/%s", shared.APIVersion, req.Name))
}

// The handler for the delete operation.
func profileDelete(d *Daemon, r *http.Request) Response {
	name := mux.Vars(r)["name"]

	_, err := doProfileGet(d, name)
	if err != nil {
		return SmartError(err)
	}

	clist := getRunningContainersWithProfile(d, name)
	if len(clist) != 0 {
		return BadRequest(fmt.Errorf("Profile is currently in use"))
	}

	err = dbProfileDelete(d.db, name)
	if err != nil {
		return SmartError(err)
	}

	return EmptySyncResponse
}

var profileCmd = Command{name: "profiles/{name}", get: profileGet, put: profilePut, delete: profileDelete, post: profilePost, patch: profilePatch}
<commit_msg>lxd/profiles: switch to new logging functions<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"reflect"
	"strings"

	"github.com/gorilla/mux"
	_ "github.com/mattn/go-sqlite3"

	"github.com/lxc/lxd/shared"

	log "gopkg.in/inconshreveable/log15.v2"
)

/* This is used for both profiles post and profile put */
type profilesPostReq struct {
	Name        string            `json:"name"`
	Config      map[string]string `json:"config"`
	Description string            `json:"description"`
	Devices     shared.Devices    `json:"devices"`
}

func profilesGet(d *Daemon, r *http.Request) Response {
	results, err := dbProfiles(d.db)
	if err != nil {
		return SmartError(err)
	}

	recursion := d.isRecursionRequest(r)

	resultString := make([]string, len(results))
	resultMap := make([]*shared.ProfileConfig, len(results))
	i := 0
	for _, name := range results {
		if !recursion {
			url := fmt.Sprintf("/%s/profiles/%s", shared.APIVersion, name)
			resultString[i] = url
		} else {
			profile, err := doProfileGet(d, name)
			if err != nil {
				shared.LogError("Failed to get profile", log.Ctx{"profile": name})
				continue
			}
			resultMap[i] = profile
		}
		i++
	}

	if !recursion {
		return SyncResponse(true, resultString)
	}

	return SyncResponse(true, resultMap)
}

func profilesPost(d *Daemon, r *http.Request) Response {
	req := profilesPostReq{}
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		return BadRequest(err)
	}

	// Sanity checks
	if req.Name == "" {
		return BadRequest(fmt.Errorf("No name provided"))
	}

	_, profile, _ := dbProfileGet(d.db, req.Name)
	if profile != nil {
		return BadRequest(fmt.Errorf("The profile already exists"))
	}

	if strings.Contains(req.Name, "/") {
		return BadRequest(fmt.Errorf("Profile names may not contain slashes"))
	}

	if shared.StringInSlice(req.Name, []string{".", ".."}) {
		return BadRequest(fmt.Errorf("Invalid profile name '%s'", req.Name))
	}

	err := containerValidConfig(d, req.Config, true, false)
	if err != nil {
		return BadRequest(err)
	}

	err = containerValidDevices(req.Devices, true, false)
	if err != nil {
		return BadRequest(err)
	}

	// Update DB entry
	_, err = dbProfileCreate(d.db, req.Name, req.Description, req.Config, req.Devices)
	if err != nil {
		return InternalError(
			fmt.Errorf("Error inserting %s into database: %s", req.Name, err))
	}

	return SyncResponseLocation(true, nil, fmt.Sprintf("/%s/profiles/%s", shared.APIVersion, req.Name))
}

var profilesCmd = Command{
	name: "profiles",
	get:  profilesGet,
	post: profilesPost}

func doProfileGet(d *Daemon, name string) (*shared.ProfileConfig, error) {
	_, profile, err := dbProfileGet(d.db, name)
	return profile, err
}

func profileGet(d *Daemon, r *http.Request) Response {
	name := mux.Vars(r)["name"]

	resp, err := doProfileGet(d, name)
	if err != nil {
		return SmartError(err)
	}

	return SyncResponseETag(true, resp, resp)
}

func getRunningContainersWithProfile(d *Daemon, profile string) []container {
	results := []container{}

	output, err := dbProfileContainersGet(d.db, profile)
	if err != nil {
		return results
	}

	for _, name := range output {
		c, err := containerLoadByName(d, name)
		if err != nil {
			shared.LogError("Failed opening container", log.Ctx{"container": name})
			continue
		}
		results = append(results, c)
	}
	return results
}

func profilePut(d *Daemon, r *http.Request) Response {
	// Get the profile
	name := mux.Vars(r)["name"]
	id, profile, err := dbProfileGet(d.db, name)
	if err != nil {
		return InternalError(fmt.Errorf("Failed to retrieve profile='%s'", name))
	}

	// Validate the ETag
	err = etagCheck(r, profile)
	if err != nil {
		return PreconditionFailed(err)
	}

	req := profilesPostReq{}
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		return BadRequest(err)
	}

	return doProfileUpdate(d, name, id, profile, req)
}

func profilePatch(d *Daemon, r *http.Request) Response {
	// Get the profile
	name := mux.Vars(r)["name"]
	id, profile, err := dbProfileGet(d.db, name)
	if err != nil {
		return InternalError(fmt.Errorf("Failed to retrieve profile='%s'", name))
	}

	// Validate the ETag
	err = etagCheck(r, profile)
	if err != nil {
		return PreconditionFailed(err)
	}

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return InternalError(err)
	}

	rdr1 := ioutil.NopCloser(bytes.NewBuffer(body))
	rdr2 := ioutil.NopCloser(bytes.NewBuffer(body))

	reqRaw := shared.Jmap{}
	if err := json.NewDecoder(rdr1).Decode(&reqRaw); err != nil {
		return BadRequest(err)
	}

	req := profilesPostReq{}
	if err := json.NewDecoder(rdr2).Decode(&req); err != nil {
		return BadRequest(err)
	}

	// Get Description
	_, err = reqRaw.GetString("description")
	if err != nil {
		req.Description = profile.Description
	}

	// Get Config
	if req.Config == nil {
		req.Config = profile.Config
	} else {
		for k, v := range profile.Config {
			_, ok := req.Config[k]
			if !ok {
				req.Config[k] = v
			}
		}
	}

	// Get Devices
	if req.Devices == nil {
		req.Devices = profile.Devices
	} else {
		for k, v := range profile.Devices {
			_, ok := req.Devices[k]
			if !ok {
				req.Devices[k] = v
			}
		}
	}

	return doProfileUpdate(d, name, id, profile, req)
}

func doProfileUpdate(d *Daemon, name string, id int64, profile *shared.ProfileConfig, req profilesPostReq) Response {
	// Sanity checks
	err := containerValidConfig(d, req.Config, true, false)
	if err != nil {
		return BadRequest(err)
	}

	err = containerValidDevices(req.Devices, true, false)
	if err != nil {
		return BadRequest(err)
	}

	// Get the running container list
	clist := getRunningContainersWithProfile(d, name)
	var containers []container
	for _, c := range clist {
		if !c.IsRunning() {
			continue
		}

		containers = append(containers, c)
	}

	// Update the database
	tx, err := dbBegin(d.db)
	if err != nil {
		return InternalError(err)
	}

	if profile.Description != req.Description {
		err = dbProfileDescriptionUpdate(tx, id, req.Description)
		if err != nil {
			tx.Rollback()
			return InternalError(err)
		}
	}

	// Optimize for description-only changes
	if reflect.DeepEqual(profile.Config, req.Config) && reflect.DeepEqual(profile.Devices, req.Devices) {
		err = txCommit(tx)
		if err != nil {
			return InternalError(err)
		}

		return EmptySyncResponse
	}

	err = dbProfileConfigClear(tx, id)
	if err != nil {
		tx.Rollback()
		return InternalError(err)
	}

	err = dbProfileConfigAdd(tx, id, req.Config)
	if err != nil {
		tx.Rollback()
		return SmartError(err)
	}

	err = dbDevicesAdd(tx, "profile", id, req.Devices)
	if err != nil {
		tx.Rollback()
		return SmartError(err)
	}

	err = txCommit(tx)
	if err != nil {
		return InternalError(err)
	}

	// Update all the containers using the profile. Must be done after txCommit due to DB lock.
	failures := map[string]error{}
	for _, c := range containers {
		err = c.Update(containerArgs{
			Architecture: c.Architecture(),
			Ephemeral:    c.IsEphemeral(),
			Config:       c.LocalConfig(),
			Devices:      c.LocalDevices(),
			Profiles:     c.Profiles()}, true)

		if err != nil {
			failures[c.Name()] = err
		}
	}

	if len(failures) != 0 {
		msg := "The following containers failed to update (profile change still saved):\n"
		for cname, err := range failures {
			msg += fmt.Sprintf(" - %s: %s\n", cname, err)
		}
		return InternalError(fmt.Errorf("%s", msg))
	}

	return EmptySyncResponse
}

// The handler for the post operation.
func profilePost(d *Daemon, r *http.Request) Response {
	name := mux.Vars(r)["name"]

	req := profilesPostReq{}
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		return BadRequest(err)
	}

	// Sanity checks
	if req.Name == "" {
		return BadRequest(fmt.Errorf("No name provided"))
	}

	// Check that the name isn't already in use
	id, _, _ := dbProfileGet(d.db, req.Name)
	if id > 0 {
		return Conflict
	}

	if strings.Contains(req.Name, "/") {
		return BadRequest(fmt.Errorf("Profile names may not contain slashes"))
	}

	if shared.StringInSlice(req.Name, []string{".", ".."}) {
		return BadRequest(fmt.Errorf("Invalid profile name '%s'", req.Name))
	}

	err := dbProfileUpdate(d.db, name, req.Name)
	if err != nil {
		return InternalError(err)
	}

	return SyncResponseLocation(true, nil, fmt.Sprintf("/%s/profiles/%s", shared.APIVersion, req.Name))
}

// The handler for the delete operation.
func profileDelete(d *Daemon, r *http.Request) Response {
	name := mux.Vars(r)["name"]

	_, err := doProfileGet(d, name)
	if err != nil {
		return SmartError(err)
	}

	clist := getRunningContainersWithProfile(d, name)
	if len(clist) != 0 {
		return BadRequest(fmt.Errorf("Profile is currently in use"))
	}

	err = dbProfileDelete(d.db, name)
	if err != nil {
		return SmartError(err)
	}

	return EmptySyncResponse
}

var profileCmd = Command{name: "profiles/{name}", get: profileGet, put: profilePut, delete: profileDelete, post: profilePost, patch: profilePatch}
<|endoftext|>


<commit_before>package visualization

import (
	"fmt"
	"strings"
	"time"

	"github.com/cloudfoundry-incubator/auction/auctiontypes"
)

const defaultStyle = "\x1b[0m"
const boldStyle = "\x1b[1m"
const redColor = "\x1b[91m"
const greenColor = "\x1b[32m"
const yellowColor = "\x1b[33m"
const cyanColor = "\x1b[36m"
const grayColor = "\x1b[90m"
const lightGrayColor = "\x1b[37m"
const purpleColor = "\x1b[35m"

func PrintReport(client auctiontypes.SimulationRepPoolClient, results []auctiontypes.StartAuctionResult, representatives []string, duration time.Duration, rules auctiontypes.StartAuctionRules) {
	roundsDistribution := map[int]int{}
	auctionedInstances := map[string]bool{}

	fmt.Printf("Finished %d Auctions among %d Representatives in %s\n", len(results), len(representatives), duration)
	fmt.Println()
	///
	fmt.Println("Rounds Distributions")
	for _, result := range results {
		roundsDistribution[result.NumRounds] += 1
		auctionedInstances[result.LRPStartAuction.InstanceGuid] = true
	}

	for i := 1; i <= rules.MaxRounds; i++ {
		if roundsDistribution[i] > 0 {
			fmt.Printf("  %2d: %d (%.1f%%)\n", i, roundsDistribution[i], float64(roundsDistribution[i])/float64(len(results))*100.0)
		}
	}

	///

	fmt.Println("Distribution")
	maxGuidLength := 0
	for _, repGuid := range representatives {
		if len(repGuid) > maxGuidLength {
			maxGuidLength = len(repGuid)
		}
	}
	guidFormat := fmt.Sprintf("%%%ds", maxGuidLength)

	numNew := 0
	for _, repGuid := range representatives {
		repString := fmt.Sprintf(guidFormat, repGuid)

		instanceString := ""
		instances := client.SimulatedInstances(repGuid)

		availableColors := []string{"red", "cyan", "yellow", "gray", "purple", "green"}
		colorLookup := map[string]string{"red": redColor, "green": greenColor, "cyan": cyanColor, "yellow": yellowColor, "gray": lightGrayColor, "purple": purpleColor}

		originalCounts := map[string]int{}
		newCounts := map[string]int{}
		totalUsage := 0
		for _, instance := range instances {
			key := "green"
			if _, ok := colorLookup[instance.ProcessGuid]; ok {
				key = instance.ProcessGuid
			}
			if auctionedInstances[instance.InstanceGuid] {
				newCounts[key] += instance.MemoryMB
				numNew += 1
			} else {
				originalCounts[key] += instance.MemoryMB
			}
			totalUsage += instance.MemoryMB
		}
		for _, col := range availableColors {
			instanceString += strings.Repeat(colorLookup[col]+"-"+defaultStyle, originalCounts[col])
			instanceString += strings.Repeat(colorLookup[col]+"+"+defaultStyle, newCounts[col])
		}
		instanceString += strings.Repeat(grayColor+"."+defaultStyle, client.TotalResources(repGuid).MemoryMB-totalUsage)

		fmt.Printf("  %s: %s\n", repString, instanceString)
	}

	if numNew < len(auctionedInstances) {
		expected := len(auctionedInstances)
		fmt.Printf("%s!!!!MISSING INSTANCES!!!!  Expected %d, got %d (%.3f %% failure rate)%s", redColor, expected, numNew, float64(expected-numNew)/float64(expected), defaultStyle)
	}

	minTime, maxTime, meanTime := time.Hour, time.Duration(0), time.Duration(0)
	for _, result := range results {
		if result.Duration < minTime {
			minTime = result.Duration
		}
		if result.Duration > maxTime {
			maxTime = result.Duration
		}
		meanTime += result.Duration
	}

	meanTime = meanTime / time.Duration(len(results))
	fmt.Printf("%14s  Min: %16s | Max: %16s | Mean: %16s\n", "Wait Times:", minTime, maxTime, meanTime)

	///

	minRounds, maxRounds, totalRounds, meanRounds := 100000000, 0, 0, float64(0)
	for _, result := range results {
		if result.NumRounds < minRounds {
			minRounds = result.NumRounds
		}
		if result.NumRounds > maxRounds {
			maxRounds = result.NumRounds
		}
		totalRounds += result.NumRounds
		meanRounds += float64(result.NumRounds)
	}

	meanRounds = meanRounds / float64(len(results))
	fmt.Printf("%14s  Min: %16d | Max: %16d | Mean: %16.2f | Total: %16d\n", "Rounds:", minRounds, maxRounds, meanRounds, totalRounds)

	///

	minCommunications, maxCommunications, totalCommunications, meanCommunications := 100000000, 0, 0, float64(0)
	for _, result := range results {
		if result.NumCommunications < minCommunications {
			minCommunications = result.NumCommunications
		}
		if result.NumCommunications > maxCommunications {
			maxCommunications = result.NumCommunications
		}
		totalCommunications += result.NumCommunications
		meanCommunications += float64(result.NumCommunications)
	}

	meanCommunications = meanCommunications / float64(len(results))
	fmt.Printf("%14s  Min: %16d | Max: %16d | Mean: %16.2f | Total: %16d\n", "Communication:", minCommunications, maxCommunications, meanCommunications, totalCommunications)
}
<commit_msg>add timing information to report<commit_after>package visualization

import (
	"fmt"
	"strings"
	"time"

	"github.com/cloudfoundry-incubator/auction/auctiontypes"
)

const defaultStyle = "\x1b[0m"
const boldStyle = "\x1b[1m"
const redColor = "\x1b[91m"
const greenColor = "\x1b[32m"
const yellowColor = "\x1b[33m"
const cyanColor = "\x1b[36m"
const grayColor = "\x1b[90m"
const lightGrayColor = "\x1b[37m"
const purpleColor = "\x1b[35m"

func PrintReport(client auctiontypes.SimulationRepPoolClient, results []auctiontypes.StartAuctionResult, representatives []string, duration time.Duration, rules auctiontypes.StartAuctionRules) {
	roundsDistribution := map[int]int{}
	roundsTimeDistributions := map[int][]time.Duration{}
	auctionedInstances := map[string]bool{}

	fmt.Printf("Finished %d Auctions among %d Representatives in %s\n", len(results), len(representatives), duration)
	fmt.Println()
	///
	fmt.Println("Rounds Distributions")
	for _, result := range results {
		roundsDistribution[result.NumRounds] += 1
		roundsTimeDistributions[result.NumRounds] = append(roundsTimeDistributions[result.NumRounds], result.Duration)
		auctionedInstances[result.LRPStartAuction.InstanceGuid] = true
	}

	for i := 1; i <= rules.MaxRounds; i++ {
		if roundsDistribution[i] > 0 {
			minTime, maxTime, meanTime := StatsForDurations(roundsTimeDistributions[i])
			percentage := fmt.Sprintf("(%.1f%%)", float64(roundsDistribution[i])/float64(len(results))*100.0)
			fmt.Printf("  %3d: %4d %7s Time: min:%16s max:%16s mean:%16s\n", i, roundsDistribution[i], percentage, minTime, maxTime, meanTime)
		}
	}

	///

	fmt.Println("Distribution")
	maxGuidLength := 0
	for _, repGuid := range representatives {
		if len(repGuid) > maxGuidLength {
			maxGuidLength = len(repGuid)
		}
	}
	guidFormat := fmt.Sprintf("%%%ds", maxGuidLength)

	numNew := 0
	for _, repGuid := range representatives {
		repString := fmt.Sprintf(guidFormat, repGuid)

		instanceString := ""
		instances := client.SimulatedInstances(repGuid)

		availableColors := []string{"red", "cyan", "yellow", "gray", "purple", "green"}
		colorLookup := map[string]string{"red": redColor, "green": greenColor, "cyan": cyanColor, "yellow": yellowColor, "gray": lightGrayColor, "purple": purpleColor}

		originalCounts := map[string]int{}
		newCounts := map[string]int{}
		totalUsage := 0
		for _, instance := range instances {
			key := "green"
			if _, ok := colorLookup[instance.ProcessGuid]; ok {
				key = instance.ProcessGuid
			}
			if auctionedInstances[instance.InstanceGuid] {
				newCounts[key] += instance.MemoryMB
				numNew += 1
			} else {
				originalCounts[key] += instance.MemoryMB
			}
			totalUsage += instance.MemoryMB
		}
		for _, col := range availableColors {
			instanceString += strings.Repeat(colorLookup[col]+"-"+defaultStyle, originalCounts[col])
			instanceString += strings.Repeat(colorLookup[col]+"+"+defaultStyle, newCounts[col])
		}
		instanceString += strings.Repeat(grayColor+"."+defaultStyle, client.TotalResources(repGuid).MemoryMB-totalUsage)

		fmt.Printf("  %s: %s\n", repString, instanceString)
	}

	if numNew < len(auctionedInstances) {
		expected := len(auctionedInstances)
		fmt.Printf("%s!!!!MISSING INSTANCES!!!!  Expected %d, got %d (%.3f %% failure rate)%s", redColor, expected, numNew, float64(expected-numNew)/float64(expected), defaultStyle)
	}

	durations := []time.Duration{}
	for _, result := range results {
		durations = append(durations, result.Duration)
	}
	minTime, maxTime, meanTime := StatsForDurations(durations)
	fmt.Printf("%14s  Min: %16s | Max: %16s | Mean: %16s\n", "Wait Times:", minTime, maxTime, meanTime)

	///

	minRounds, maxRounds, totalRounds, meanRounds := 100000000, 0, 0, float64(0)
	for _, result := range results {
		if result.NumRounds < minRounds {
			minRounds = result.NumRounds
		}
		if result.NumRounds > maxRounds {
			maxRounds = result.NumRounds
		}
		totalRounds += result.NumRounds
		meanRounds += float64(result.NumRounds)
	}

	meanRounds = meanRounds / float64(len(results))
	fmt.Printf("%14s  Min: %16d | Max: %16d | Mean: %16.2f | Total: %16d\n", "Rounds:", minRounds, maxRounds, meanRounds, totalRounds)

	///

	minCommunications, maxCommunications, totalCommunications, meanCommunications := 100000000, 0, 0, float64(0)
	for _, result := range results {
		if result.NumCommunications < minCommunications {
			minCommunications = result.NumCommunications
		}
		if result.NumCommunications > maxCommunications {
			maxCommunications = result.NumCommunications
		}
		totalCommunications += result.NumCommunications
		meanCommunications += float64(result.NumCommunications)
	}

	meanCommunications = meanCommunications / float64(len(results))
	fmt.Printf("%14s  Min: %16d | Max: %16d | Mean: %16.2f | Total: %16d\n", "Communication:", minCommunications, maxCommunications, meanCommunications, totalCommunications)
}

func StatsForDurations(durations []time.Duration) (time.Duration, time.Duration, time.Duration) {
	minTime, maxTime, meanTime := time.Hour, time.Duration(0), time.Duration(0)
	for _, duration := range durations {
		if duration < minTime {
			minTime = duration
		}
		if duration > maxTime {
			maxTime = duration
		}
		meanTime += duration
	}
	if len(durations) > 0 {
		meanTime = meanTime / time.Duration(len(durations))
	}

	return minTime, maxTime, meanTime
}
<|endoftext|>


<commit_before>// Copyright 2014 Vic Demuzere
//
// Use of this source code is governed by the MIT license.

package irc

import (
	"reflect"
	"testing"
)

type messageTest struct {
	parsed     *Message
	rawMessage string
	rawPrefix  string
	hostmask   bool // Is it very clear that the prefix is a hostname?
	server     bool // Is the prefix a servername?
}

var messageTests = [...]*messageTest{
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "syrk",
				User: "kalt",
				Host: "millennium.stealth.net",
			},
			Command:  "QUIT",
			Trailing: "Gone to have lunch",
		},
		rawMessage: ":syrk!kalt@millennium.stealth.net QUIT :Gone to have lunch",
		rawPrefix:  "syrk!kalt@millennium.stealth.net",
		hostmask:   true,
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "Trillian",
			},
			Command:  "SQUIT",
			Params:   []string{"cm22.eng.umd.edu"},
			Trailing: "Server out of control",
		},
		rawMessage: ":Trillian SQUIT cm22.eng.umd.edu :Server out of control",
		rawPrefix:  "Trillian",
		server:     true,
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "WiZ",
				User: "jto",
				Host: "tolsun.oulu.fi",
			},
			Command: "JOIN",
			Params:  []string{"#Twilight_zone"},
		},
		rawMessage: ":WiZ!jto@tolsun.oulu.fi JOIN #Twilight_zone",
		rawPrefix:  "WiZ!jto@tolsun.oulu.fi",
		hostmask:   true,
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "WiZ",
				User: "jto",
				Host: "tolsun.oulu.fi",
			},
			Command:  "PART",
			Params:   []string{"#playzone"},
			Trailing: "I lost",
		},
		rawMessage: ":WiZ!jto@tolsun.oulu.fi PART #playzone :I lost",
		rawPrefix:  "WiZ!jto@tolsun.oulu.fi",
		hostmask:   true,
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "WiZ",
				User: "jto",
				Host: "tolsun.oulu.fi",
			},
			Command: "MODE",
			Params:  []string{"#eu-opers", "-l"},
		},
		rawMessage: ":WiZ!jto@tolsun.oulu.fi MODE #eu-opers -l",
		rawPrefix:  "WiZ!jto@tolsun.oulu.fi",
		hostmask:   true,
	},
	{
		parsed: &Message{
			Command: "MODE",
			Params:  []string{"&oulu", "+b", "*!*@*.edu", "+e", "*!*@*.bu.edu"},
		},
		rawMessage: "MODE &oulu +b *!*@*.edu +e *!*@*.bu.edu",
	},
	{
		parsed: &Message{
			Command:  "PRIVMSG",
			Params:   []string{"#channel"},
			Trailing: "Message with :colons!",
		},
		rawMessage: "PRIVMSG #channel :Message with :colons!",
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "irc.vives.lan",
			},
			Command:  "251",
			Params:   []string{"test"},
			Trailing: "There are 2 users and 0 services on 1 servers",
		},
		rawMessage: ":irc.vives.lan 251 test :There are 2 users and 0 services on 1 servers",
		rawPrefix:  "irc.vives.lan",
		server:     true,
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "irc.vives.lan",
			},
			Command:  "376",
			Params:   []string{"test"},
			Trailing: "End of MOTD command",
		},
		rawMessage: ":irc.vives.lan 376 test :End of MOTD command",
		rawPrefix:  "irc.vives.lan",
		server:     true,
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "irc.vives.lan",
			},
			Command:  "250",
			Params:   []string{"test"},
			Trailing: "Highest connection count: 1 (1 connections received)",
		},
		rawMessage: ":irc.vives.lan 250 test :Highest connection count: 1 (1 connections received)",
		rawPrefix:  "irc.vives.lan",
		server:     true,
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "sorcix",
				User: "~sorcix",
				Host: "sorcix.users.quakenet.org",
			},
			Command:  "PRIVMSG",
			Params:   []string{"#viveslan"},
			Trailing: "\001ACTION is testing CTCP messages!\001",
		},
		rawMessage: ":sorcix!~sorcix@sorcix.users.quakenet.org PRIVMSG #viveslan :\001ACTION is testing CTCP messages!\001",
		rawPrefix:  "sorcix!~sorcix@sorcix.users.quakenet.org",
		hostmask:   true,
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "sorcix",
				User: "~sorcix",
				Host: "sorcix.users.quakenet.org",
			},
			Command:  "NOTICE",
			Params:   []string{"midnightfox"},
			Trailing: "\001PONG 1234567890\001",
		},
		rawMessage: ":sorcix!~sorcix@sorcix.users.quakenet.org NOTICE midnightfox :\001PONG 1234567890\001",
		rawPrefix:  "sorcix!~sorcix@sorcix.users.quakenet.org",
		hostmask:   true,
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "a",
				User: "b",
				Host: "c",
			},
			Command: "QUIT",
		},
		rawMessage: ":a!b@c QUIT",
		rawPrefix:  "a!b@c",
		hostmask:   true,
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "a",
				User: "b",
			},
			Command:  "PRIVMSG",
			Trailing: "message",
		},
		rawMessage: ":a!b PRIVMSG :message",
		rawPrefix:  "a!b",
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "a",
				Host: "c",
			},
			Command:  "NOTICE",
			Trailing: ":::Hey!",
		},
		rawMessage: ":a@c NOTICE ::::Hey!",
		rawPrefix:  "a@c",
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "nick",
			},
			Command:  "PRIVMSG",
			Params:   []string{"$@"},
			Trailing: "This message contains a\ttab!",
		},
		rawMessage: ":nick PRIVMSG $@ :This message contains a\ttab!",
		rawPrefix:  "nick",
	},
	{
		parsed: &Message{
			Command:  "TEST",
			Params:   []string{"$@", "", "param"},
			Trailing: "Trailing",
		},
		rawMessage: "TEST $@  param :Trailing",
	},
	{
		rawMessage: ": PRIVMSG test :Invalid message with empty prefix.",
		rawPrefix:  "",
	},
	{
		rawMessage: ":  PRIVMSG test :Invalid message with space prefix",
		rawPrefix:  " ",
	},
}

// -----
// PREFIX
// -----

func TestPrefix_IsHostmask(t *testing.T) {

	for i, test := range messageTests {

		// Skip tests that have no prefix
		if test.parsed == nil || test.parsed.Prefix == nil {
			continue
		}

		if test.hostmask && !test.parsed.Prefix.IsHostmask() {
			t.Errorf("Prefix %d should be recognized as a hostmask!", i)
		}

	}
}

func TestPrefix_IsServer(t *testing.T) {

	for i, test := range messageTests {

		// Skip tests that have no prefix
		if test.parsed == nil || test.parsed.Prefix == nil {
			continue
		}

		if test.server && !test.parsed.Prefix.IsServer() {
			t.Errorf("Prefix %d should be recognized as a server!", i)
		}

	}
}

func TestPrefix_String(t *testing.T) {
	var s string

	for i, test := range messageTests {

		// Skip tests that have no prefix
		if test.parsed == nil || test.parsed.Prefix == nil {
			continue
		}

		// Convert the prefix
		s = test.parsed.Prefix.String()

		// Result should be the same as the value in rawMessage.
		if s != test.rawPrefix {
			t.Errorf("Failed to stringify prefix %d:", i)
			t.Logf("Output: %s", s)
			t.Logf("Expected: %s", test.rawPrefix)
		}
	}
}

func TestPrefix_Len(t *testing.T) {
	var l int

	for i, test := range messageTests {

		// Skip tests that have no prefix
		if test.parsed == nil || test.parsed.Prefix == nil {
			continue
		}

		l = test.parsed.Prefix.Len()

		// Result should be the same as the value in rawMessage.
		if l != len(test.rawPrefix) {
			t.Errorf("Failed to calculate prefix length %d:", i)
			t.Logf("Output: %d", l)
			t.Logf("Expected: %d", len(test.rawPrefix))
		}
	}
}

func TestParsePrefix(t *testing.T) {
	var p *Prefix

	for i, test := range messageTests {

		// Skip tests that have no prefix
		if test.parsed == nil || test.parsed.Prefix == nil {
			continue
		}

		// Parse the prefix
		p = ParsePrefix(test.rawPrefix)

		// Result struct should be the same as the value in parsed.
		if *p != *test.parsed.Prefix {
			t.Errorf("Failed to parse prefix %d:", i)
			t.Logf("Output: %#v", p)
			t.Logf("Expected: %#v", test.parsed.Prefix)
		}
	}
}

// -----
// MESSAGE
// -----

func TestMessage_String(t *testing.T) {
	var s string

	for i, test := range messageTests {

		// Skip tests that have no valid struct
		if test.parsed == nil {
			continue
		}

		// Convert the prefix
		s = test.parsed.String()

		// Result should be the same as the value in rawMessage.
		if s != test.rawMessage {
			t.Errorf("Failed to stringify message %d:", i)
			t.Logf("Output: %s", s)
			t.Logf("Expected: %s", test.rawMessage)
		}
	}
}

func TestMessage_Len(t *testing.T) {
	var l int

	for i, test := range messageTests {

		// Skip tests that have no valid struct
		if test.parsed == nil {
			continue
		}

		l = test.parsed.Len()

		// Result should be the same as the value in rawMessage.
		if l != len(test.rawMessage) {
			t.Errorf("Failed to calculate message length %d:", i)
			t.Logf("Output: %d", l)
			t.Logf("Expected: %d", len(test.rawMessage))
		}
	}
}

func TestParseMessage(t *testing.T) {
	var p *Message

	for i, test := range messageTests {

		// Parse the prefix
		p = ParseMessage(test.rawMessage)

		// Result struct should be the same as the value in parsed.
		if !reflect.DeepEqual(p, test.parsed) {
			t.Errorf("Failed to parse message %d:", i)
			t.Logf("Output: %#v", p)
			t.Logf("Expected: %#v", test.parsed)
		}
	}
}

// -----
// BENCHMARK
// -----

func BenchmarkPrefix_String_short(b *testing.B) {
	b.ReportAllocs()

	prefix := new(Prefix)
	prefix.Name = "Namename"

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		prefix.String()
	}
}
func BenchmarkPrefix_String_long(b *testing.B) {
	b.ReportAllocs()

	prefix := new(Prefix)
	prefix.Name = "Namename"
	prefix.User = "Username"
	prefix.Host = "Hostname"

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		prefix.String()
	}
}
func BenchmarkParsePrefix_short(b *testing.B) {
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		ParsePrefix("Namename")
	}
}
func BenchmarkParsePrefix_long(b *testing.B) {
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		ParsePrefix("Namename!Username@Hostname")
	}
}
func BenchmarkMessage_String(b *testing.B) {
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		messageTests[0].parsed.String()
	}
}
func BenchmarkParseMessage_short(b *testing.B) {
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		ParseMessage("COMMAND arg1 :Message\r\n")
	}
}
func BenchmarkParseMessage_medium(b *testing.B) {
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		ParseMessage(":Namename COMMAND arg6 arg7 :Message message message\r\n")
	}
}
func BenchmarkParseMessage_long(b *testing.B) {
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		ParseMessage(":Namename!username@hostname COMMAND arg1 arg2 arg3 arg4 arg5 arg6 arg7 :Message message message message message\r\n")
	}
}
<commit_msg>Use anonymous structs for Message tests.<commit_after>// Copyright 2014 Vic Demuzere
//
// Use of this source code is governed by the MIT license.

package irc

import (
	"reflect"
	"testing"
)

var messageTests = [...]*struct {
	parsed     *Message
	rawMessage string
	rawPrefix  string
	hostmask   bool // Is it very clear that the prefix is a hostname?
	server     bool // Is the prefix a servername?
}{
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "syrk",
				User: "kalt",
				Host: "millennium.stealth.net",
			},
			Command:  "QUIT",
			Trailing: "Gone to have lunch",
		},
		rawMessage: ":syrk!kalt@millennium.stealth.net QUIT :Gone to have lunch",
		rawPrefix:  "syrk!kalt@millennium.stealth.net",
		hostmask:   true,
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "Trillian",
			},
			Command:  "SQUIT",
			Params:   []string{"cm22.eng.umd.edu"},
			Trailing: "Server out of control",
		},
		rawMessage: ":Trillian SQUIT cm22.eng.umd.edu :Server out of control",
		rawPrefix:  "Trillian",
		server:     true,
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "WiZ",
				User: "jto",
				Host: "tolsun.oulu.fi",
			},
			Command: "JOIN",
			Params:  []string{"#Twilight_zone"},
		},
		rawMessage: ":WiZ!jto@tolsun.oulu.fi JOIN #Twilight_zone",
		rawPrefix:  "WiZ!jto@tolsun.oulu.fi",
		hostmask:   true,
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "WiZ",
				User: "jto",
				Host: "tolsun.oulu.fi",
			},
			Command:  "PART",
			Params:   []string{"#playzone"},
			Trailing: "I lost",
		},
		rawMessage: ":WiZ!jto@tolsun.oulu.fi PART #playzone :I lost",
		rawPrefix:  "WiZ!jto@tolsun.oulu.fi",
		hostmask:   true,
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "WiZ",
				User: "jto",
				Host: "tolsun.oulu.fi",
			},
			Command: "MODE",
			Params:  []string{"#eu-opers", "-l"},
		},
		rawMessage: ":WiZ!jto@tolsun.oulu.fi MODE #eu-opers -l",
		rawPrefix:  "WiZ!jto@tolsun.oulu.fi",
		hostmask:   true,
	},
	{
		parsed: &Message{
			Command: "MODE",
			Params:  []string{"&oulu", "+b", "*!*@*.edu", "+e", "*!*@*.bu.edu"},
		},
		rawMessage: "MODE &oulu +b *!*@*.edu +e *!*@*.bu.edu",
	},
	{
		parsed: &Message{
			Command:  "PRIVMSG",
			Params:   []string{"#channel"},
			Trailing: "Message with :colons!",
		},
		rawMessage: "PRIVMSG #channel :Message with :colons!",
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "irc.vives.lan",
			},
			Command:  "251",
			Params:   []string{"test"},
			Trailing: "There are 2 users and 0 services on 1 servers",
		},
		rawMessage: ":irc.vives.lan 251 test :There are 2 users and 0 services on 1 servers",
		rawPrefix:  "irc.vives.lan",
		server:     true,
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "irc.vives.lan",
			},
			Command:  "376",
			Params:   []string{"test"},
			Trailing: "End of MOTD command",
		},
		rawMessage: ":irc.vives.lan 376 test :End of MOTD command",
		rawPrefix:  "irc.vives.lan",
		server:     true,
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "irc.vives.lan",
			},
			Command:  "250",
			Params:   []string{"test"},
			Trailing: "Highest connection count: 1 (1 connections received)",
		},
		rawMessage: ":irc.vives.lan 250 test :Highest connection count: 1 (1 connections received)",
		rawPrefix:  "irc.vives.lan",
		server:     true,
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "sorcix",
				User: "~sorcix",
				Host: "sorcix.users.quakenet.org",
			},
			Command:  "PRIVMSG",
			Params:   []string{"#viveslan"},
			Trailing: "\001ACTION is testing CTCP messages!\001",
		},
		rawMessage: ":sorcix!~sorcix@sorcix.users.quakenet.org PRIVMSG #viveslan :\001ACTION is testing CTCP messages!\001",
		rawPrefix:  "sorcix!~sorcix@sorcix.users.quakenet.org",
		hostmask:   true,
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "sorcix",
				User: "~sorcix",
				Host: "sorcix.users.quakenet.org",
			},
			Command:  "NOTICE",
			Params:   []string{"midnightfox"},
			Trailing: "\001PONG 1234567890\001",
		},
		rawMessage: ":sorcix!~sorcix@sorcix.users.quakenet.org NOTICE midnightfox :\001PONG 1234567890\001",
		rawPrefix:  "sorcix!~sorcix@sorcix.users.quakenet.org",
		hostmask:   true,
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "a",
				User: "b",
				Host: "c",
			},
			Command: "QUIT",
		},
		rawMessage: ":a!b@c QUIT",
		rawPrefix:  "a!b@c",
		hostmask:   true,
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "a",
				User: "b",
			},
			Command:  "PRIVMSG",
			Trailing: "message",
		},
		rawMessage: ":a!b PRIVMSG :message",
		rawPrefix:  "a!b",
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "a",
				Host: "c",
			},
			Command:  "NOTICE",
			Trailing: ":::Hey!",
		},
		rawMessage: ":a@c NOTICE ::::Hey!",
		rawPrefix:  "a@c",
	},
	{
		parsed: &Message{
			Prefix: &Prefix{
				Name: "nick",
			},
			Command:  "PRIVMSG",
			Params:   []string{"$@"},
			Trailing: "This message contains a\ttab!",
		},
		rawMessage: ":nick PRIVMSG $@ :This message contains a\ttab!",
		rawPrefix:  "nick",
	},
	{
		parsed: &Message{
			Command:  "TEST",
			Params:   []string{"$@", "", "param"},
			Trailing: "Trailing",
		},
		rawMessage: "TEST $@  param :Trailing",
	},
	{
		rawMessage: ": PRIVMSG test :Invalid message with empty prefix.",
		rawPrefix:  "",
	},
	{
		rawMessage: ":  PRIVMSG test :Invalid message with space prefix",
		rawPrefix:  " ",
	},
}

// -----
// PREFIX
// -----

func TestPrefix_IsHostmask(t *testing.T) {

	for i, test := range messageTests {

		// Skip tests that have no prefix
		if test.parsed == nil || test.parsed.Prefix == nil {
			continue
		}

		if test.hostmask && !test.parsed.Prefix.IsHostmask() {
			t.Errorf("Prefix %d should be recognized as a hostmask!", i)
		}

	}
}

func TestPrefix_IsServer(t *testing.T) {

	for i, test := range messageTests {

		// Skip tests that have no prefix
		if test.parsed == nil || test.parsed.Prefix == nil {
			continue
		}

		if test.server && !test.parsed.Prefix.IsServer() {
			t.Errorf("Prefix %d should be recognized as a server!", i)
		}

	}
}

func TestPrefix_String(t *testing.T) {
	var s string

	for i, test := range messageTests {

		// Skip tests that have no prefix
		if test.parsed == nil || test.parsed.Prefix == nil {
			continue
		}

		// Convert the prefix
		s = test.parsed.Prefix.String()

		// Result should be the same as the value in rawMessage.
		if s != test.rawPrefix {
			t.Errorf("Failed to stringify prefix %d:", i)
			t.Logf("Output: %s", s)
			t.Logf("Expected: %s", test.rawPrefix)
		}
	}
}

func TestPrefix_Len(t *testing.T) {
	var l int

	for i, test := range messageTests {

		// Skip tests that have no prefix
		if test.parsed == nil || test.parsed.Prefix == nil {
			continue
		}

		l = test.parsed.Prefix.Len()

		// Result should be the same as the value in rawMessage.
		if l != len(test.rawPrefix) {
			t.Errorf("Failed to calculate prefix length %d:", i)
			t.Logf("Output: %d", l)
			t.Logf("Expected: %d", len(test.rawPrefix))
		}
	}
}

func TestParsePrefix(t *testing.T) {
	var p *Prefix

	for i, test := range messageTests {

		// Skip tests that have no prefix
		if test.parsed == nil || test.parsed.Prefix == nil {
			continue
		}

		// Parse the prefix
		p = ParsePrefix(test.rawPrefix)

		// Result struct should be the same as the value in parsed.
		if *p != *test.parsed.Prefix {
			t.Errorf("Failed to parse prefix %d:", i)
			t.Logf("Output: %#v", p)
			t.Logf("Expected: %#v", test.parsed.Prefix)
		}
	}
}

// -----
// MESSAGE
// -----

func TestMessage_String(t *testing.T) {
	var s string

	for i, test := range messageTests {

		// Skip tests that have no valid struct
		if test.parsed == nil {
			continue
		}

		// Convert the prefix
		s = test.parsed.String()

		// Result should be the same as the value in rawMessage.
		if s != test.rawMessage {
			t.Errorf("Failed to stringify message %d:", i)
			t.Logf("Output: %s", s)
			t.Logf("Expected: %s", test.rawMessage)
		}
	}
}

func TestMessage_Len(t *testing.T) {
	var l int

	for i, test := range messageTests {

		// Skip tests that have no valid struct
		if test.parsed == nil {
			continue
		}

		l = test.parsed.Len()

		// Result should be the same as the value in rawMessage.
		if l != len(test.rawMessage) {
			t.Errorf("Failed to calculate message length %d:", i)
			t.Logf("Output: %d", l)
			t.Logf("Expected: %d", len(test.rawMessage))
		}
	}
}

func TestParseMessage(t *testing.T) {
	var p *Message

	for i, test := range messageTests {

		// Parse the prefix
		p = ParseMessage(test.rawMessage)

		// Result struct should be the same as the value in parsed.
		if !reflect.DeepEqual(p, test.parsed) {
			t.Errorf("Failed to parse message %d:", i)
			t.Logf("Output: %#v", p)
			t.Logf("Expected: %#v", test.parsed)
		}
	}
}

// -----
// BENCHMARK
// -----

func BenchmarkPrefix_String_short(b *testing.B) {
	b.ReportAllocs()

	prefix := new(Prefix)
	prefix.Name = "Namename"

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		prefix.String()
	}
}
func BenchmarkPrefix_String_long(b *testing.B) {
	b.ReportAllocs()

	prefix := new(Prefix)
	prefix.Name = "Namename"
	prefix.User = "Username"
	prefix.Host = "Hostname"

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		prefix.String()
	}
}
func BenchmarkParsePrefix_short(b *testing.B) {
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		ParsePrefix("Namename")
	}
}
func BenchmarkParsePrefix_long(b *testing.B) {
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		ParsePrefix("Namename!Username@Hostname")
	}
}
func BenchmarkMessage_String(b *testing.B) {
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		messageTests[0].parsed.String()
	}
}
func BenchmarkParseMessage_short(b *testing.B) {
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		ParseMessage("COMMAND arg1 :Message\r\n")
	}
}
func BenchmarkParseMessage_medium(b *testing.B) {
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		ParseMessage(":Namename COMMAND arg6 arg7 :Message message message\r\n")
	}
}
func BenchmarkParseMessage_long(b *testing.B) {
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		ParseMessage(":Namename!username@hostname COMMAND arg1 arg2 arg3 arg4 arg5 arg6 arg7 :Message message message message message\r\n")
	}
}
<|endoftext|>


<commit_before>package method

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"strconv"
	"strings"

	"log"

	"net/http"
	"net/url"

	"github.com/gorilla/schema"
)

//GivenGene given Create table to store refGene
func (s *Service) GivenGene(w http.ResponseWriter, r *http.Request) {
	params := r.URL.Query()
	q, err := queryParams(params)
	if err != nil {
		log.Fatal(err)
	}
	log.Println(params)
	var geneRows []*Gene
	sql := q.refGeneSQL()
	udb := s.db.Unsafe()
	err = udb.Select(&geneRows, sql)
	if err != nil {
		log.Fatal(err)
	}
	log.Println("Query result is on the way...")

	body, err := json.MarshalIndent(geneRows, "", "    ")
	if err != nil {
		log.Fatal(err)
	}
	w.Write(body)
}

func queryParams(uv url.Values) (q *Query, err error) {
	q = new(Query)
	dec := schema.NewDecoder()
	dec.IgnoreUnknownKeys(true)
	if err = dec.Decode(q, uv); err != nil {
		log.Fatal(err)
		return
	}
	return
}

func (q *Query) refGeneSQL() (sql string) {
	var whereConds []string
	var where string
	if q.Start != 0 {
		whereConds = append(whereConds, "txStart>"+strconv.Itoa(q.Start))
	}
	if q.End != 0 {
		whereConds = append(whereConds, "txEnd>"+strconv.Itoa(q.End))
	}
	if q.Gene != "" {
		whereConds = append(whereConds, "name2='"+q.Gene+"'")
	}
	if q.Gene != "" {
		whereConds = append(whereConds, "name='"+q.ModeName+"'")
	}
	if len(whereConds) >= 1 {
		where = "where " + strings.Join(whereConds, " and ")
	}
	sql = fmt.Sprintf(`select name,
							  chrom,
							  strand,
							  txStart,
							  txEnd,
							  cdsStart,
							  cdsEnd,
							  exonCount,
							  exonStarts,
							  exonEnds,
                              score,
							  name2 gene,
							  exonFrames
					   from hg38.refGene
                       %s`, where)
	//limit 1,5`, where)
	return
}

// TruncateTable Truncate data in the table
func TruncateTable(table string, db *sql.DB) {

	truncate, err := db.Prepare("Truncate " + table) // ? = placeholder
	if err != nil {
		panic(err.Error())
	}
	defer truncate.Close()
	_, err = truncate.Exec()
	if err != nil {
		panic(err.Error())
	}
	fmt.Printf("Truncate table chr successfully!\n")
}

// dumpLoad Truncate data in the table
func dumpLoad(refGene string, db *sql.DB) {
	/*
		readerName := "r" + strconv.Itoa(rand.Int())
		mysql.RegisterReaderHandler(readerName,
			func() io.Reader {
				return bytes.NewBufferString(refGene)
			})
		defer mysql.DeregisterReaderHandler(readerName)
		cmd := "LOAD DATA LOCAL INFILE 'Reader::" + readerName + "' " +
			"IGNORE INTO TABLE chr "
		_, err := db.Exec(cmd)
		if err != nil {
			panic(err.Error())
		}*/
}
<commit_msg>Fix backend package SQL statement issue<commit_after>package method

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"strconv"
	"strings"

	"log"

	"net/http"
	"net/url"

	"github.com/gorilla/schema"
)

//GivenGene given Create table to store refGene
func (s *Service) GivenGene(w http.ResponseWriter, r *http.Request) {
	params := r.URL.Query()
	q, err := queryParams(params)
	if err != nil {
		log.Fatal(err)
	}
	log.Println(params)
	var geneRows []*Gene
	sql := q.refGeneSQL()
	udb := s.db.Unsafe()
	err = udb.Select(&geneRows, sql)
	if err != nil {
		log.Fatal(err)
	}
	log.Println("Query result is on the way...")

	body, err := json.MarshalIndent(geneRows, "", "    ")
	if err != nil {
		log.Fatal(err)
	}
	w.Write(body)
}

func queryParams(uv url.Values) (q *Query, err error) {
	q = new(Query)
	dec := schema.NewDecoder()
	dec.IgnoreUnknownKeys(true)
	if err = dec.Decode(q, uv); err != nil {
		log.Fatal(err)
		return
	}
	return
}

func (q *Query) refGeneSQL() (sql string) {
	var whereConds []string
	var where string
	if q.Start != 0 {
		whereConds = append(whereConds, "txStart>"+strconv.Itoa(q.Start))
	}
	if q.End != 0 {
		whereConds = append(whereConds, "txEnd>"+strconv.Itoa(q.End))
	}
	if q.Gene != "" {
		whereConds = append(whereConds, "name2='"+q.Gene+"'")
	}
	if q.ModeName != "" {
		whereConds = append(whereConds, "name='"+q.ModeName+"'")
	}
	if len(whereConds) >= 1 {
		where = "where " + strings.Join(whereConds, " and ")
	}
	sql = fmt.Sprintf(`select name,
							  chrom,
							  strand,
							  txStart,
							  txEnd,
							  cdsStart,
							  cdsEnd,
							  exonCount,
							  exonStarts,
							  exonEnds,
                              score,
							  name2 gene,
							  exonFrames
					   from hg38.refGene
                       %s`, where)
	//limit 1,5`, where)
	//fmt.Println(sql)
	return
}

// TruncateTable Truncate data in the table
func TruncateTable(table string, db *sql.DB) {

	truncate, err := db.Prepare("Truncate " + table) // ? = placeholder
	if err != nil {
		panic(err.Error())
	}
	defer truncate.Close()
	_, err = truncate.Exec()
	if err != nil {
		panic(err.Error())
	}
	fmt.Printf("Truncate table chr successfully!\n")
}

// dumpLoad Truncate data in the table
func dumpLoad(refGene string, db *sql.DB) {
	/*
		readerName := "r" + strconv.Itoa(rand.Int())
		mysql.RegisterReaderHandler(readerName,
			func() io.Reader {
				return bytes.NewBufferString(refGene)
			})
		defer mysql.DeregisterReaderHandler(readerName)
		cmd := "LOAD DATA LOCAL INFILE 'Reader::" + readerName + "' " +
			"IGNORE INTO TABLE chr "
		_, err := db.Exec(cmd)
		if err != nil {
			panic(err.Error())
		}*/
}
<|endoftext|>


<commit_before>package glib

import (
	"testing"
	"fmt"
)

// GLib values
func TestValue(t *testing.T) {
	v1 := uint64(0xdeadbeaf)
	a := ValueOf(v1)
	b := DefaultValue(TYPE_UINT64)
	a.Copy(b)
	t.Logf("a = %s(%s), b = %s(%s)", a.Type(), a, b.Type(), b)
	if b.Get().(uint64) != v1 {
		t.Error("TYPE_UINT64")
	}
	v2 := -1
	a = ValueOf(v2)
	b = DefaultValue(TYPE_INT)
	a.Copy(b)
	t.Logf("a = %s(%s), b = %s(%s)", a.Type(), a, b.Type(), b)
	if b.Get() != v2 {
		t.Error("TYPE_INT")
	}
}

// Signals by ID
func TestSignal(t *testing.T) {
	// An object on which the signal will be emitted
	o := NewObject(TYPE_OBJECT, nil)

	// The new signal without return value, which can be emitted on TYPE_OBJECT
	// and accepts one parameter of type TYPE_GO_INT
	s := NewSignal("sig1", TYPE_NONE, o.Type(), TYPE_GO_INT)
	t.Logf("Signal: %s", s)

	// The Go variable of type A that have some methods. These methods will be
	// used as signal handlers.
	a := A("Test with IDs")

	// Connect a.handler(*Object, int) to the signal.
	// o will be passed as its first argument. Second argument of type int will
	// be passed from second argument passed to Emit function.
	o.ConnectSid(s, (*A).handler, &a)

	// Connect a.noiHandler(int) to the signal.
	// o will not be passed to the method. An argument of type int will be
	// passed from second argument passed to Emit function.
	o.ConnectSidNoi(s, (*A).noiHandler, &a)

	// Connect funcHandler(*Object, int)to the signal.
	// o will be passed as its first argument. Second argument of type int
	// will be passed from second argument passed to Emit function.
	o.ConnectSid(s, funcHandler, nil)

	// Connect funcNoiHandler(int) to the signal.
	// o will not be passed to the function. An argument of type int will be
	// passed from second argument passed to the Emit function.
	o.ConnectSidNoi(s, funcNoiHandler, nil)

	// Connect funcHandlerParam0(A, *Object, int) to the signal.
	// &a will be passed as its first argument, o will be passed as its second
	// argument. The thrid argument of type int will be from second argument
	// passed to the Emit function.
	o.ConnectSid(s, funcHandlerParam0, &a)

	// Emit signal with 123 integer as argument.
	o.EmitById(s, 123)
}

// Like TestSignal but uses signal names
func TestSignalName(t *testing.T) {
	o := NewObject(TYPE_OBJECT, nil)

	NewSignal("sig2", TYPE_NONE, TYPE_OBJECT, TYPE_GO_INT)

	a := A("Test with names")

	o.Connect("sig2", (*A).handler, &a)
	o.ConnectNoi("sig2", (*A).noiHandler, &a)
	o.Connect("sig2", funcHandler, nil)
	o.ConnectNoi("sig2", funcNoiHandler, nil)
	o.Connect("sig2", funcHandlerParam0, &a)

	o.Emit("sig2", 456)
}

type A string

func (a *A) handler(o *Object, i int) {
	fmt.Printf("handler: %s, %v, %d\n", a, o, i)
}

func (a *A) noiHandler(i int) {
	fmt.Printf("noiHandler: %s, %d\n", a, i)
}

func funcHandler(o *Object, i int) {
	fmt.Printf("funcHandler: %v, %d\n", o, i)
}

func funcNoiHandler(i int) {
	fmt.Printf("funcNoiHandler: %d\n", i)
}

func funcHandlerParam0(a *A, o *Object, i int) {
	fmt.Printf("funcHandlerParam0: %s %v %d\n", a, o, i)
}
<commit_msg>Some fixes<commit_after>package glib

import (
	"testing"
	"fmt"
)

// GLib values
func TestValue(t *testing.T) {
	v1 := uint64(0xdeadbeaf)
	a := ValueOf(v1)
	b := DefaultValue(TYPE_UINT64)
	a.Copy(b)
	t.Logf("a = %s(%s), b = %s(%s)", a.Type(), a, b.Type(), b)
	if b.Get().(uint64) != v1 {
		t.Error("TYPE_UINT64")
	}
	v2 := -1
	a = ValueOf(v2)
	b = DefaultValue(TYPE_INT)
	a.Copy(b)
	t.Logf("a = %s(%s), b = %s(%s)", a.Type(), a, b.Type(), b)
	if b.Get() != v2 {
		t.Error("TYPE_INT")
	}
}

// Signals by ID
func TestSignal(t *testing.T) {
	// An object on which the signal will be emitted
	o := NewObject(TYPE_OBJECT, nil)

	// The new signal without return value, which can be emitted on TYPE_OBJECT
	// and accepts one parameter of type TYPE_GO_INT
	s := NewSignal("sig1", TYPE_NONE, o.Type(), TYPE_GO_INT)
	t.Logf("Signal: %s", s)

	// The Go variable of type A that have some methods. These methods will be
	// used as signal handlers.
	a := A("Test with IDs")

	// Connect a.handler(*Object, int) to the signal.
	// o will be passed as its first argument. Second argument of type int will
	// be passed from second argument passed to the Emit function.
	o.ConnectSid(s, (*A).handler, &a)

	// Connect a.noiHandler(int) to the signal.
	// o will not be passed to the method. An argument of type int will be
	// passed from second argument passed to the Emit function.
	o.ConnectSidNoi(s, (*A).noiHandler, &a)

	// Connect funcHandler(*Object, int)to the signal.
	// o will be passed as its first argument. Second argument of type int
	// will be passed from second argument passed to the Emit function.
	o.ConnectSid(s, funcHandler, nil)

	// Connect funcNoiHandler(int) to the signal.
	// o will not be passed to the function. An argument of type int will be
	// passed from second argument passed to the Emit function.
	o.ConnectSidNoi(s, funcNoiHandler, nil)

	// Connect funcHandlerParam0(A, *Object, int) to the signal.
	// &a will be passed as its first argument, o will be passed as its second
	// argument. The thrid argument of type int will be from second argument
	// passed to the Emit function.
	o.ConnectSid(s, funcHandlerParam0, &a)

	// Emit signal with 123 integer as argument.
	o.EmitById(s, 123)
}

// Like TestSignal but uses signal names
func TestSignalName(t *testing.T) {
	o := NewObject(TYPE_OBJECT, nil)

	NewSignal("sig2", TYPE_NONE, TYPE_OBJECT, TYPE_GO_INT)

	a := A("Test with names")

	o.Connect("sig2", (*A).handler, &a)
	o.ConnectNoi("sig2", (*A).noiHandler, &a)
	o.Connect("sig2", funcHandler, nil)
	o.ConnectNoi("sig2", funcNoiHandler, nil)
	o.Connect("sig2", funcHandlerParam0, &a)

	o.Emit("sig2", 456)
}

type A string

func (a *A) handler(o *Object, i int) {
	fmt.Printf("handler: %s, %v, %d\n", a, o, i)
}

func (a *A) noiHandler(i int) {
	fmt.Printf("noiHandler: %s, %d\n", a, i)
}

func funcHandler(o *Object, i int) {
	fmt.Printf("funcHandler: %v, %d\n", o, i)
}

func funcNoiHandler(i int) {
	fmt.Printf("funcNoiHandler: %d\n", i)
}

func funcHandlerParam0(a *A, o *Object, i int) {
	fmt.Printf("funcHandlerParam0: %s %v %d\n", a, o, i)
}
<|endoftext|>


<commit_before>// Package host is an implementation of the host module, and is responsible for
// storing data and advertising available storage to the network.
package host

import (
	"errors"
	"net"
	"sync"

	"github.com/NebulousLabs/Sia/build"
	"github.com/NebulousLabs/Sia/crypto"
	"github.com/NebulousLabs/Sia/modules"
	"github.com/NebulousLabs/Sia/persist"
	"github.com/NebulousLabs/Sia/types"
)

const (
	maxContractLen      = 1 << 16   // The maximum allowed size of a file contract coming in over the wire. This does not include the file.
	defaultTotalStorage = 10e9      // 10 GB.
	defaultMaxDuration  = 144 * 120 // 120 days.
)

var (
	// defaultPrice defines the starting price for hosts selling storage. We
	// try to match a number that is both reasonably profitable and reasonably
	// competitive.
	defaultPrice = types.SiacoinPrecision.Div(types.NewCurrency64(4320e9)).Mul(types.NewCurrency64(100)) // 100 SC / GB / Month

	// defaultCollateral defines the amount of money that the host puts up as
	// collateral per-byte by default. Set to zero currently because neither of
	// the negotiation protocols have logic to deal with non-zero collateral.
	defaultCollateral = types.NewCurrency64(0)

	// defaultWindowSize is the size of the proof of storage window requested
	// by the host. The host will not delete any obligations until the window
	// has closed and buried under several confirmations.
	defaultWindowSize = func() types.BlockHeight {
		if build.Release == "testing" {
			return 5
		}
		if build.Release == "standard" {
			return 36
		}
		if build.Release == "dev" {
			return 36
		}
		panic("unrecognized release constant in host")
	}()

	// errChangedUnlockHash is returned by SetSettings if the unlock hash has
	// changed, an illegal operation.
	errChangedUnlockHash = errors.New("cannot change the unlock hash in SetSettings")

	// errHostClosed gets returned when a call is rejected due to the host
	// having been closed.
	errHostClosed = errors.New("call is disabled because the host is closed")

	// Nil dependency errors.
	errNilCS     = errors.New("host cannot use a nil state")
	errNilTpool  = errors.New("host cannot use a nil transaction pool")
	errNilWallet = errors.New("host cannot use a nil wallet")
)

// A Host contains all the fields necessary for storing files for clients and
// performing the storage proofs on the received files.
type Host struct {
	// Module dependencies.
	cs     modules.ConsensusSet
	tpool  modules.TransactionPool
	wallet modules.Wallet

	// Consensus Tracking. 'actionItems' lists a bunch of contract obligations
	// that have 'todos' at a given height. The required action ranges from
	// needed to resubmit a revision to handling a storage proof or getting
	// pruned from the host.
	blockHeight  types.BlockHeight
	recentChange modules.ConsensusChangeID
	actionItems  map[types.BlockHeight]map[types.FileContractID]*contractObligation

	// Host Identity
	netAddress modules.NetAddress
	publicKey  types.SiaPublicKey
	secretKey  crypto.SecretKey

	// File Management.
	obligationsByID map[types.FileContractID]*contractObligation

	// Statistics
	anticipatedRevenue types.Currency
	fileCounter        int64
	lostRevenue        types.Currency
	revenue            types.Currency
	spaceRemaining     int64

	// RPC Tracking
	atomicErroredCalls   uint64
	atomicMalformedCalls uint64
	atomicDownloadCalls  uint64
	atomicRenewCalls     uint64
	atomicReviseCalls    uint64
	atomicSettingsCalls  uint64
	atomicUploadCalls    uint64

	// The resource lock is held by threaded functions for the duration of
	// their operation. Functions should grab the resource lock as a read lock
	// unless they are planning on manipulating the 'closed' variable.
	// Readlocks are used so that multiple functions can use resources
	// simultaneously, but the resources are not closed until all functions
	// accessing them have returned.
	closed       bool
	resourceLock sync.RWMutex

	// Utilities.
	listener   net.Listener
	log        *persist.Logger
	mu         sync.RWMutex
	persistDir string
	settings   modules.HostSettings
}

// New returns an initialized Host.
func New(cs modules.ConsensusSet, tpool modules.TransactionPool, wallet modules.Wallet, address string, persistDir string) (*Host, error) {
	// Check that all the dependencies were provided.
	if cs == nil {
		return nil, errNilCS
	}
	if tpool == nil {
		return nil, errNilTpool
	}
	if wallet == nil {
		return nil, errNilWallet
	}

	// Create the host object.
	h := &Host{
		cs:     cs,
		tpool:  tpool,
		wallet: wallet,

		actionItems: make(map[types.BlockHeight]map[types.FileContractID]*contractObligation),

		obligationsByID: make(map[types.FileContractID]*contractObligation),

		persistDir: persistDir,
	}

	// Load all of the saved host state into the host.
	err := h.initPersist()
	if err != nil {
		return nil, err
	}

	// Get the host established on the network.
	err = h.initNetworking(address)
	if err != nil {
		return nil, err
	}

	return h, nil
}

// Close shuts down the host, preparing it for garbage collection.
func (h *Host) Close() error {
	// Unsubscribe the host from the consensus set. Call will not terminate
	// until the last consensus update has been sent to the host.
	// Unsubscription must happen before any resources are released or
	// terminated because the process consensus change function makes use of
	// those resources.
	h.cs.Unsubscribe(h)

	// Close the listener, which means incoming network connections will be
	// rejected. The listener should be closed before the host resources are
	// disabled, as incoming connections will want to use the hosts resources.
	err := h.listener.Close()
	if err != nil {
		return err
	}

	// Manage the port forwarding.
	err = h.clearPort(h.netAddress.Port())
	if err != nil {
		return err
	}

	// Grab the resource lock and indicate that the host is closing. Concurrent
	// functions hold the resource lock until they terminate, meaning that no
	// threaded function will be running by the time the resource lock is
	// acquired.
	h.resourceLock.Lock()
	h.closed = true
	h.resourceLock.Unlock()

	// Save the latest host state.
	h.mu.Lock()
	err = h.save()
	h.mu.Unlock()
	if err != nil {
		return err
	}

	// Close the logger.
	err = h.log.Close()
	if err != nil {
		return err
	}
	return nil
}

// addActionItem adds an action item at the given height for the given contract
// obligation.
func (h *Host) addActionItem(height types.BlockHeight, co *contractObligation) {
	_, exists := h.actionItems[height]
	if !exists {
		h.actionItems[height] = make(map[types.FileContractID]*contractObligation)
	}
	h.actionItems[height][co.ID] = co
}

// Capacity returns the amount of storage still available on the machine. The
// amount can be negative if the total capacity was reduced to below the active
// capacity.
func (h *Host) Capacity() int64 {
	h.mu.RLock()
	defer h.mu.RUnlock()
	return h.spaceRemaining
}

// Contracts returns the number of unresolved file contracts that the host is
// responsible for.
func (h *Host) Contracts() uint64 {
	h.mu.RLock()
	defer h.mu.RUnlock()
	return uint64(len(h.obligationsByID))
}

// NetAddress returns the address at which the host can be reached.
func (h *Host) NetAddress() modules.NetAddress {
	h.mu.RLock()
	defer h.mu.RUnlock()
	return h.netAddress
}

// Revenue returns the amount of revenue that the host has lined up, as well as
// the amount of revenue that the host has successfully captured.
func (h *Host) Revenue() (unresolved, resolved types.Currency) {
	h.mu.RLock()
	defer h.mu.RUnlock()
	return h.anticipatedRevenue, h.revenue
}

// SetSettings updates the host's internal HostSettings object.
func (h *Host) SetSettings(settings modules.HostSettings) error {
	h.mu.Lock()
	defer h.mu.Unlock()
	h.resourceLock.RLock()
	defer h.resourceLock.RUnlock()
	if h.closed {
		return errHostClosed
	}

	// Check that the unlock hash was not changed.
	if settings.UnlockHash != h.settings.UnlockHash {
		return errChangedUnlockHash
	}

	// Update the amount of space remaining to reflect the new volume of total
	// storage.
	h.spaceRemaining += settings.TotalStorage - h.settings.TotalStorage

	h.settings = settings
	return h.save()
}

// Settings returns the settings of a host.
func (h *Host) Settings() modules.HostSettings {
	h.mu.RLock()
	defer h.mu.RUnlock()
	return h.settings
}
<commit_msg>move atomic fields in host<commit_after>// Package host is an implementation of the host module, and is responsible for
// storing data and advertising available storage to the network.
package host

import (
	"errors"
	"net"
	"sync"

	"github.com/NebulousLabs/Sia/build"
	"github.com/NebulousLabs/Sia/crypto"
	"github.com/NebulousLabs/Sia/modules"
	"github.com/NebulousLabs/Sia/persist"
	"github.com/NebulousLabs/Sia/types"
)

const (
	maxContractLen      = 1 << 16   // The maximum allowed size of a file contract coming in over the wire. This does not include the file.
	defaultTotalStorage = 10e9      // 10 GB.
	defaultMaxDuration  = 144 * 120 // 120 days.
)

var (
	// defaultPrice defines the starting price for hosts selling storage. We
	// try to match a number that is both reasonably profitable and reasonably
	// competitive.
	defaultPrice = types.SiacoinPrecision.Div(types.NewCurrency64(4320e9)).Mul(types.NewCurrency64(100)) // 100 SC / GB / Month

	// defaultCollateral defines the amount of money that the host puts up as
	// collateral per-byte by default. Set to zero currently because neither of
	// the negotiation protocols have logic to deal with non-zero collateral.
	defaultCollateral = types.NewCurrency64(0)

	// defaultWindowSize is the size of the proof of storage window requested
	// by the host. The host will not delete any obligations until the window
	// has closed and buried under several confirmations.
	defaultWindowSize = func() types.BlockHeight {
		if build.Release == "testing" {
			return 5
		}
		if build.Release == "standard" {
			return 36
		}
		if build.Release == "dev" {
			return 36
		}
		panic("unrecognized release constant in host")
	}()

	// errChangedUnlockHash is returned by SetSettings if the unlock hash has
	// changed, an illegal operation.
	errChangedUnlockHash = errors.New("cannot change the unlock hash in SetSettings")

	// errHostClosed gets returned when a call is rejected due to the host
	// having been closed.
	errHostClosed = errors.New("call is disabled because the host is closed")

	// Nil dependency errors.
	errNilCS     = errors.New("host cannot use a nil state")
	errNilTpool  = errors.New("host cannot use a nil transaction pool")
	errNilWallet = errors.New("host cannot use a nil wallet")
)

// A Host contains all the fields necessary for storing files for clients and
// performing the storage proofs on the received files.
type Host struct {
	// RPC Tracking - atomic variables need to be placed at the top to preserve
	// compatibility with 32bit systems.
	atomicErroredCalls   uint64
	atomicMalformedCalls uint64
	atomicDownloadCalls  uint64
	atomicRenewCalls     uint64
	atomicReviseCalls    uint64
	atomicSettingsCalls  uint64
	atomicUploadCalls    uint64

	// Module dependencies.
	cs     modules.ConsensusSet
	tpool  modules.TransactionPool
	wallet modules.Wallet

	// Consensus Tracking. 'actionItems' lists a bunch of contract obligations
	// that have 'todos' at a given height. The required action ranges from
	// needed to resubmit a revision to handling a storage proof or getting
	// pruned from the host.
	blockHeight  types.BlockHeight
	recentChange modules.ConsensusChangeID
	actionItems  map[types.BlockHeight]map[types.FileContractID]*contractObligation

	// Host Identity
	netAddress modules.NetAddress
	publicKey  types.SiaPublicKey
	secretKey  crypto.SecretKey

	// File Management.
	obligationsByID map[types.FileContractID]*contractObligation

	// Statistics
	anticipatedRevenue types.Currency
	fileCounter        int64
	lostRevenue        types.Currency
	revenue            types.Currency
	spaceRemaining     int64

	// The resource lock is held by threaded functions for the duration of
	// their operation. Functions should grab the resource lock as a read lock
	// unless they are planning on manipulating the 'closed' variable.
	// Readlocks are used so that multiple functions can use resources
	// simultaneously, but the resources are not closed until all functions
	// accessing them have returned.
	closed       bool
	resourceLock sync.RWMutex

	// Utilities.
	listener   net.Listener
	log        *persist.Logger
	mu         sync.RWMutex
	persistDir string
	settings   modules.HostSettings
}

// New returns an initialized Host.
func New(cs modules.ConsensusSet, tpool modules.TransactionPool, wallet modules.Wallet, address string, persistDir string) (*Host, error) {
	// Check that all the dependencies were provided.
	if cs == nil {
		return nil, errNilCS
	}
	if tpool == nil {
		return nil, errNilTpool
	}
	if wallet == nil {
		return nil, errNilWallet
	}

	// Create the host object.
	h := &Host{
		cs:     cs,
		tpool:  tpool,
		wallet: wallet,

		actionItems: make(map[types.BlockHeight]map[types.FileContractID]*contractObligation),

		obligationsByID: make(map[types.FileContractID]*contractObligation),

		persistDir: persistDir,
	}

	// Load all of the saved host state into the host.
	err := h.initPersist()
	if err != nil {
		return nil, err
	}

	// Get the host established on the network.
	err = h.initNetworking(address)
	if err != nil {
		return nil, err
	}

	return h, nil
}

// Close shuts down the host, preparing it for garbage collection.
func (h *Host) Close() error {
	// Unsubscribe the host from the consensus set. Call will not terminate
	// until the last consensus update has been sent to the host.
	// Unsubscription must happen before any resources are released or
	// terminated because the process consensus change function makes use of
	// those resources.
	h.cs.Unsubscribe(h)

	// Close the listener, which means incoming network connections will be
	// rejected. The listener should be closed before the host resources are
	// disabled, as incoming connections will want to use the hosts resources.
	err := h.listener.Close()
	if err != nil {
		return err
	}

	// Manage the port forwarding.
	err = h.clearPort(h.netAddress.Port())
	if err != nil {
		return err
	}

	// Grab the resource lock and indicate that the host is closing. Concurrent
	// functions hold the resource lock until they terminate, meaning that no
	// threaded function will be running by the time the resource lock is
	// acquired.
	h.resourceLock.Lock()
	h.closed = true
	h.resourceLock.Unlock()

	// Save the latest host state.
	h.mu.Lock()
	err = h.save()
	h.mu.Unlock()
	if err != nil {
		return err
	}

	// Close the logger.
	err = h.log.Close()
	if err != nil {
		return err
	}
	return nil
}

// addActionItem adds an action item at the given height for the given contract
// obligation.
func (h *Host) addActionItem(height types.BlockHeight, co *contractObligation) {
	_, exists := h.actionItems[height]
	if !exists {
		h.actionItems[height] = make(map[types.FileContractID]*contractObligation)
	}
	h.actionItems[height][co.ID] = co
}

// Capacity returns the amount of storage still available on the machine. The
// amount can be negative if the total capacity was reduced to below the active
// capacity.
func (h *Host) Capacity() int64 {
	h.mu.RLock()
	defer h.mu.RUnlock()
	return h.spaceRemaining
}

// Contracts returns the number of unresolved file contracts that the host is
// responsible for.
func (h *Host) Contracts() uint64 {
	h.mu.RLock()
	defer h.mu.RUnlock()
	return uint64(len(h.obligationsByID))
}

// NetAddress returns the address at which the host can be reached.
func (h *Host) NetAddress() modules.NetAddress {
	h.mu.RLock()
	defer h.mu.RUnlock()
	return h.netAddress
}

// Revenue returns the amount of revenue that the host has lined up, as well as
// the amount of revenue that the host has successfully captured.
func (h *Host) Revenue() (unresolved, resolved types.Currency) {
	h.mu.RLock()
	defer h.mu.RUnlock()
	return h.anticipatedRevenue, h.revenue
}

// SetSettings updates the host's internal HostSettings object.
func (h *Host) SetSettings(settings modules.HostSettings) error {
	h.mu.Lock()
	defer h.mu.Unlock()
	h.resourceLock.RLock()
	defer h.resourceLock.RUnlock()
	if h.closed {
		return errHostClosed
	}

	// Check that the unlock hash was not changed.
	if settings.UnlockHash != h.settings.UnlockHash {
		return errChangedUnlockHash
	}

	// Update the amount of space remaining to reflect the new volume of total
	// storage.
	h.spaceRemaining += settings.TotalStorage - h.settings.TotalStorage

	h.settings = settings
	return h.save()
}

// Settings returns the settings of a host.
func (h *Host) Settings() modules.HostSettings {
	h.mu.RLock()
	defer h.mu.RUnlock()
	return h.settings
}
<|endoftext|>


<commit_before>package main

import (
	"html/template"
	"log"
	"net/http"
)

// GLOBALS DECLARED HERE

var root = "/path/to/media"
var tmpl_dir = "./templates/"
var templates map[string]*template.Template
var pageData = PageData{}

// THE VIEW CODE IS HERE

func GenerateTemplates() {
	templates = make(map[string]*template.Template)
	modulus := template.FuncMap{"mod": func(i, j int) bool { return i%j == 0 }}
	templates_list := []string{"index.html", "about.html", "movie.html", "alreadyplaying.html"}
	for _, tmpl := range templates_list {
		t := template.New("base.html").Funcs(modulus)
		templates[tmpl] = template.Must(t.ParseFiles(tmpl_dir+"base.html", tmpl_dir+tmpl))

	}
}

func renderTemplate(w http.ResponseWriter, tmpl string) {
	err := templates[tmpl].Execute(w, pageData)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

// HANDLERS ARE HERE

func indexHandler(w http.ResponseWriter, r *http.Request) {
	err := r.ParseForm()

	if err == nil {
		tmpl := "index.html"
		if r.Method == "GET" {
			if pageData.Player.Playing {
				tmpl = "alreadyplaying.html"
			}
		} else if r.Method == "POST" {
			if pageData.Player.Playing {
				player := pageData.Player
				currentFilm := pageData.CurrentFilm
				pageData = PageData{}
				err = GenerateMovies()
				if err == nil {
					pageData.CurrentFilm = currentFilm
					pageData.Player = player
					tmpl = "alreadyplaying.html"
				}
			} else {
				pageData = PageData{}
				err = GenerateMovies()
			}
		}
		if err == nil {
			renderTemplate(w, tmpl)
		} else {
			log.Printf("Following error occurred: %v\n", err)
		}
	}
}

func aboutHandler(w http.ResponseWriter, r *http.Request) {
	renderTemplate(w, "about.html")
}

func movieHandler(w http.ResponseWriter, r *http.Request) {
	err error
	command := r.URL.Query().Get("command")
	film := r.URL.Query().Get("movie")
	if pageData.Player.Playing == false {
		err = pageData.Player.StartFilm(film)
		if err == nil {
			pageData.CurrentFilm = film
		}
	} else if pageData.Player.Playing && (film == "" || pageData.Player.FilmName == film) {
		if len(command) != 0 {
			if command == "kill" {
				err = pageData.Player.EndFilm()
				if err == nil {
					http.Redirect(w, r, "/", http.StatusFound)
					return
				}
			} else {
				err = pageData.Player.SendCommandToFilm(command)
			}
		}
	} else {
		http.Redirect(w, r, "/", http.StatusFound)
		return
	}
	if err == nil {
	renderTemplate(w, "movie.html")
	} else {
		log.Printf("Following error occurred: %v\n", err)
	}
}

// IT ALL STARTS HERE

func main() {
	err := GenerateMovies()
	if err == nil {
		GenerateTemplates()
		http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
		http.HandleFunc("/", indexHandler)
		http.HandleFunc("/about", aboutHandler)
		http.HandleFunc("/movie", movieHandler)
		http.ListenAndServe(":8080", nil)
	} else {
		log.Printf("Following error occurred: %v\n", err)
	}

}
<commit_msg>missing var declaration<commit_after>package main

import (
	"html/template"
	"log"
	"net/http"
)

// GLOBALS DECLARED HERE

var root = "/path/to/media"
var tmpl_dir = "./templates/"
var templates map[string]*template.Template
var pageData = PageData{}

// THE VIEW CODE IS HERE

func GenerateTemplates() {
	templates = make(map[string]*template.Template)
	modulus := template.FuncMap{"mod": func(i, j int) bool { return i%j == 0 }}
	templates_list := []string{"index.html", "about.html", "movie.html", "alreadyplaying.html"}
	for _, tmpl := range templates_list {
		t := template.New("base.html").Funcs(modulus)
		templates[tmpl] = template.Must(t.ParseFiles(tmpl_dir+"base.html", tmpl_dir+tmpl))

	}
}

func renderTemplate(w http.ResponseWriter, tmpl string) {
	err := templates[tmpl].Execute(w, pageData)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

// HANDLERS ARE HERE

func indexHandler(w http.ResponseWriter, r *http.Request) {
	err := r.ParseForm()

	if err == nil {
		tmpl := "index.html"
		if r.Method == "GET" {
			if pageData.Player.Playing {
				tmpl = "alreadyplaying.html"
			}
		} else if r.Method == "POST" {
			if pageData.Player.Playing {
				player := pageData.Player
				currentFilm := pageData.CurrentFilm
				pageData = PageData{}
				err = GenerateMovies()
				if err == nil {
					pageData.CurrentFilm = currentFilm
					pageData.Player = player
					tmpl = "alreadyplaying.html"
				}
			} else {
				pageData = PageData{}
				err = GenerateMovies()
			}
		}
		if err == nil {
			renderTemplate(w, tmpl)
		} else {
			log.Printf("Following error occurred: %v\n", err)
		}
	}
}

func aboutHandler(w http.ResponseWriter, r *http.Request) {
	renderTemplate(w, "about.html")
}

func movieHandler(w http.ResponseWriter, r *http.Request) {
	var err error
	command := r.URL.Query().Get("command")
	film := r.URL.Query().Get("movie")
	if pageData.Player.Playing == false {
		err = pageData.Player.StartFilm(film)
		if err == nil {
			pageData.CurrentFilm = film
		}
	} else if pageData.Player.Playing && (film == "" || pageData.Player.FilmName == film) {
		if len(command) != 0 {
			if command == "kill" {
				err = pageData.Player.EndFilm()
				if err == nil {
					http.Redirect(w, r, "/", http.StatusFound)
					return
				}
			} else {
				err = pageData.Player.SendCommandToFilm(command)
			}
		}
	} else {
		http.Redirect(w, r, "/", http.StatusFound)
		return
	}
	if err == nil {
		renderTemplate(w, "movie.html")
	} else {
		log.Printf("Following error occurred: %v\n", err)
	}
}

// IT ALL STARTS HERE

func main() {
	err := GenerateMovies()
	if err == nil {
		GenerateTemplates()
		http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
		http.HandleFunc("/", indexHandler)
		http.HandleFunc("/about", aboutHandler)
		http.HandleFunc("/movie", movieHandler)
		http.ListenAndServe(":8080", nil)
	} else {
		log.Printf("Following error occurred: %v\n", err)
	}

}
<|endoftext|>


<commit_before>package main

import (
	"html/template"
	"log"
	"net/http"
)

// GLOBALS DECLARED HERE

var media_dir = "/path/to/media"
var tmpl_dir = "./templates/"
var templates map[string]*template.Template
var pageData = PageData{}

// THE VIEW CODE IS HERE

func GenerateTemplates() {
	templates = make(map[string]*template.Template)
	modulus := template.FuncMap{"mod": func(i, j int) bool { return i%j == 0 }}
	templates_list := []string{"index.html", "about.html", "movie.html", "alreadyplaying.html"}
	for _, tmpl := range templates_list {
		t := template.New("base.html").Funcs(modulus)
		templates[tmpl] = template.Must(t.ParseFiles(tmpl_dir+"base.html", tmpl_dir+tmpl))
	}
}

func renderTemplate(w http.ResponseWriter, tmpl string) {
	err := templates[tmpl].Execute(w, pageData)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

// HANDLERS ARE HERE

func indexHandler(w http.ResponseWriter, r *http.Request) {
	err := r.ParseForm()
	if err != nil {
		panic(err)
	}
	tmpl := "index.html"
	switch r.Method {
	case "GET":
		if pageData.Player.Playing {
			tmpl = "alreadyplaying.html"
		}
	case "POST":
		if pageData.Player.Playing {
			player := pageData.Player
			currentFilm := pageData.CurrentFilm
			pageData = PageData{}
			err = GenerateMovies(media_dir)
			if err != nil {
				panic(err)
			}
			pageData.CurrentFilm = currentFilm
			pageData.Player = player
			tmpl = "alreadyplaying.html"
		} else {
			pageData = PageData{}
			err = GenerateMovies(media_dir)
			if err != nil {
				panic(err)
			}
		}
	}
	renderTemplate(w, tmpl)
}

func aboutHandler(w http.ResponseWriter, r *http.Request) {
	renderTemplate(w, "about.html")
}

func movieHandler(w http.ResponseWriter, r *http.Request) {
	var err error
	command := r.URL.Query().Get("command")
	film := r.URL.Query().Get("movie")
	if pageData.Player.Playing == false {
		err = pageData.Player.StartFilm(film)
		if err == nil {
			pageData.CurrentFilm = film
		}
	} else if pageData.Player.Playing && (film == "" || pageData.Player.FilmName == film) {
		if len(command) != 0 {
			if command == "kill" {
				err = pageData.Player.EndFilm()
				if err == nil {
					http.Redirect(w, r, "/", http.StatusFound)
					return
				}
			} else {
				err = pageData.Player.SendCommandToFilm(command)
			}
		}
	} else {
		http.Redirect(w, r, "/", http.StatusFound)
		return
	}
	if err == nil {
		renderTemplate(w, "movie.html")
	} else {
		log.Printf("Following error occurred: %v\n", err)
	}
}

// IT ALL STARTS HERE

func main() {
	err := GenerateMovies(media_dir)
	if err == nil {
		GenerateTemplates()
		http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
		http.HandleFunc("/", indexHandler)
		http.HandleFunc("/about", aboutHandler)
		http.HandleFunc("/movie", movieHandler)
		http.ListenAndServe(":8080", nil)
	} else {
		panic(err)
	}
}
<commit_msg>have improved error handling and code readability in movieHandler function<commit_after>package main

import (
	"html/template"
	"log"
	"net/http"
)

// GLOBALS DECLARED HERE

var media_dir = "/path/to/media"
var tmpl_dir = "./templates/"
var templates map[string]*template.Template
var pageData = PageData{}

// THE VIEW CODE IS HERE

func GenerateTemplates() {
	templates = make(map[string]*template.Template)
	modulus := template.FuncMap{"mod": func(i, j int) bool { return i%j == 0 }}
	templates_list := []string{"index.html", "about.html", "movie.html", "alreadyplaying.html"}
	for _, tmpl := range templates_list {
		t := template.New("base.html").Funcs(modulus)
		templates[tmpl] = template.Must(t.ParseFiles(tmpl_dir+"base.html", tmpl_dir+tmpl))
	}
}

func renderTemplate(w http.ResponseWriter, tmpl string) {
	err := templates[tmpl].Execute(w, pageData)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

// HANDLERS ARE HERE

func indexHandler(w http.ResponseWriter, r *http.Request) {
	err := r.ParseForm()
	if err != nil {
		panic(err)
	}
	tmpl := "index.html"
	switch r.Method {
	case "GET":
		if pageData.Player.Playing {
			tmpl = "alreadyplaying.html"
		}
	case "POST":
		if pageData.Player.Playing {
			player := pageData.Player
			currentFilm := pageData.CurrentFilm
			pageData = PageData{}
			err = GenerateMovies(media_dir)
			if err != nil {
				panic(err)
			}
			pageData.CurrentFilm = currentFilm
			pageData.Player = player
			tmpl = "alreadyplaying.html"
		} else {
			pageData = PageData{}
			err = GenerateMovies(media_dir)
			if err != nil {
				panic(err)
			}
		}
	}
	renderTemplate(w, tmpl)
}

func aboutHandler(w http.ResponseWriter, r *http.Request) {
	renderTemplate(w, "about.html")
}

func movieHandler(w http.ResponseWriter, r *http.Request) {
	command := r.URL.Query().Get("command")
	film := r.URL.Query().Get("movie")

	if pageData.Player.Playing == false {
		if film == "" {
			log.Println("No film was selected")
			http.Redirect(w, r, "/", http.StatusFound)
			return
		}
		err := pageData.Player.StartFilm(film)
		if err != nil {
			log.Printf("Following error occurred: %v\n", err)
			http.Redirect(w, r, "/", http.StatusFound)
			return
		}
		pageData.CurrentFilm = film
	} else if pageData.Player.Playing && (film == "" || pageData.Player.FilmName == film) {
		if command == "kill" {
			err := pageData.Player.EndFilm()
			if err != nil {
				log.Printf("Following error occurred: %v\n", err)
			}
			http.Redirect(w, r, "/", http.StatusFound)
			return
		} else if command != "" {
			err := pageData.Player.SendCommandToFilm(command)
			if err != nil {
				log.Printf("Following error occurred: %v\n", err)
			}
		}
	} else {
		http.Redirect(w, r, "/", http.StatusFound)
		return
	}
	renderTemplate(w, "movie.html")
}

// IT ALL STARTS HERE

func main() {
	err := GenerateMovies(media_dir)
	if err == nil {
		GenerateTemplates()
		http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
		http.HandleFunc("/", indexHandler)
		http.HandleFunc("/about", aboutHandler)
		http.HandleFunc("/movie", movieHandler)
		http.ListenAndServe(":8080", nil)
	} else {
		panic(err)
	}
}
<|endoftext|>


<commit_before>// goforever - processes management
// Copyright (c) 2013 Garrett Woodworth (https://github.com/gwoo).

package main

import (
	"flag"
	"fmt"
	"log"
	"os"

	"github.com/gwoo/greq"
)

var conf = flag.String("conf", "goforever.toml", "Path to config file.")
var config *Config
var daemon *Process

var Usage = func() {
	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
	flag.PrintDefaults()
	usage := `
Commands
  list              List processes.
  show [name]       Show main proccess or named process.
  start [name]      Start main proccess or named process.
  stop [name]       Stop main proccess or named process.
  restart [name]    Restart main proccess or named process.
`
	fmt.Fprintln(os.Stderr, usage)
}

func init() {
	flag.Usage = Usage
	flag.Parse()
	setConfig()
	daemon = &Process{
		Name:    "goforever",
		Args:    []string{},
		Command: "goforever",
		Pidfile: config.Pidfile,
		Logfile: config.Logfile,
		Errfile: config.Errfile,
		Respawn: 1,
	}
}

func main() {
	if len(flag.Args()) > 0 {
		fmt.Printf("%s", Cli())
		return
	}
	if len(flag.Args()) == 0 {
		RunDaemon()
		HttpServer()
		return
	}
}

func Cli() string {
	var o []byte
	var err error
	sub := flag.Arg(0)
	name := flag.Arg(1)
	req := greq.New(host(), true)
	if sub == "list" {
		o, _, err = req.Get("/")
	}
	if name == "" {
		if sub == "start" {
			daemon.Args = append(daemon.Args, os.Args[2:]...)
			return daemon.start(daemon.Name)
		}
		_, _, err = daemon.find()
		if err != nil {
			return fmt.Sprintf("Error: %s.\n", err)
		}
		if sub == "show" {
			return fmt.Sprintf("%s.\n", daemon.String())
		}
		if sub == "stop" {
			message := daemon.stop()
			return message
		}
		if sub == "restart" {
			ch, message := daemon.restart()
			fmt.Print(message)
			return fmt.Sprintf("%s\n", <-ch)
		}
	}
	if name != "" {
		path := fmt.Sprintf("/%s", name)
		switch sub {
		case "show":
			o, _, err = req.Get(path)
		case "start":
			o, _, err = req.Post(path, nil)
		case "stop":
			o, _, err = req.Delete(path)
		case "restart":
			o, _, err = req.Put(path, nil)
		}
	}
	if err != nil {
		fmt.Printf("Process error: %s", err)
	}
	return fmt.Sprintf("%s\n", o)
}

func RunDaemon() {
	daemon.children = make(map[string]*Process, 0)
	for _, name := range config.Keys() {
		daemon.children[name] = config.Get(name)
	}
	daemon.run()
}

func setConfig() {
	var err error
	config, err = LoadConfig(*conf)
	if err != nil {
		log.Fatalf("%s", err)
		return
	}
	if config.Username == "" {
		log.Fatalf("Config error: %s", "Please provide a username.")
		return
	}
	if config.Password == "" {
		log.Fatalf("Config error: %s", "Please provide a password.")
		return
	}
	if config.Port == "" {
		config.Port = "2224"
	}
}

func host() string {
	scheme := "https"
	if isHttps() == false {
		scheme = "http"
	}
	return fmt.Sprintf("%s://%s:%s@0.0:%s",
		scheme, config.Username, config.Password, config.Port,
	)
}
<commit_msg>Parse of 0.0 doesn't work everywhere (e.g. Solaris)<commit_after>// goforever - processes management
// Copyright (c) 2013 Garrett Woodworth (https://github.com/gwoo).

package main

import (
	"flag"
	"fmt"
	"log"
	"os"

	"github.com/gwoo/greq"
)

var conf = flag.String("conf", "goforever.toml", "Path to config file.")
var config *Config
var daemon *Process

var Usage = func() {
	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
	flag.PrintDefaults()
	usage := `
Commands
  list              List processes.
  show [name]       Show main proccess or named process.
  start [name]      Start main proccess or named process.
  stop [name]       Stop main proccess or named process.
  restart [name]    Restart main proccess or named process.
`
	fmt.Fprintln(os.Stderr, usage)
}

func init() {
	flag.Usage = Usage
	flag.Parse()
	setConfig()
	daemon = &Process{
		Name:    "goforever",
		Args:    []string{},
		Command: "goforever",
		Pidfile: config.Pidfile,
		Logfile: config.Logfile,
		Errfile: config.Errfile,
		Respawn: 1,
	}
}

func main() {
	if len(flag.Args()) > 0 {
		fmt.Printf("%s", Cli())
		return
	}
	if len(flag.Args()) == 0 {
		RunDaemon()
		HttpServer()
		return
	}
}

func Cli() string {
	var o []byte
	var err error
	sub := flag.Arg(0)
	name := flag.Arg(1)
	req := greq.New(host(), true)
	if sub == "list" {
		o, _, err = req.Get("/")
	}
	if name == "" {
		if sub == "start" {
			daemon.Args = append(daemon.Args, os.Args[2:]...)
			return daemon.start(daemon.Name)
		}
		_, _, err = daemon.find()
		if err != nil {
			return fmt.Sprintf("Error: %s.\n", err)
		}
		if sub == "show" {
			return fmt.Sprintf("%s.\n", daemon.String())
		}
		if sub == "stop" {
			message := daemon.stop()
			return message
		}
		if sub == "restart" {
			ch, message := daemon.restart()
			fmt.Print(message)
			return fmt.Sprintf("%s\n", <-ch)
		}
	}
	if name != "" {
		path := fmt.Sprintf("/%s", name)
		switch sub {
		case "show":
			o, _, err = req.Get(path)
		case "start":
			o, _, err = req.Post(path, nil)
		case "stop":
			o, _, err = req.Delete(path)
		case "restart":
			o, _, err = req.Put(path, nil)
		}
	}
	if err != nil {
		fmt.Printf("Process error: %s", err)
	}
	return fmt.Sprintf("%s\n", o)
}

func RunDaemon() {
	daemon.children = make(map[string]*Process, 0)
	for _, name := range config.Keys() {
		daemon.children[name] = config.Get(name)
	}
	daemon.run()
}

func setConfig() {
	var err error
	config, err = LoadConfig(*conf)
	if err != nil {
		log.Fatalf("%s", err)
		return
	}
	if config.Username == "" {
		log.Fatalf("Config error: %s", "Please provide a username.")
		return
	}
	if config.Password == "" {
		log.Fatalf("Config error: %s", "Please provide a password.")
		return
	}
	if config.Port == "" {
		config.Port = "2224"
	}
}

func host() string {
	scheme := "https"
	if isHttps() == false {
		scheme = "http"
	}
	return fmt.Sprintf("%s://%s:%s@0.0.0.0:%s",
		scheme, config.Username, config.Password, config.Port,
	)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	//	"math/big"
	//	"github.com/fenglyu/projecteuler/golang/common"
)

func CircurLength(n int) int {
	a := 1
	b := n
	c := 0
	t := 0
	hash := make(map[int]int)

	for {
		if c >= 100 || hash[a] > 0 {
			break
		}

		hash[a]++
		//		fmt.Println(a, "/", b, "=") //, n)
		a = a % b * 10
		t++
		c++
	}
	/*
		fmt.Println(t, c)
		fmt.Println(hash)
		fmt.Println(t - hash[a])
	*/

	return t - hash[a]
	// https://www.xarg.org/puzzle/project-euler/problem-26/
}

func main() {

	/*
		fmt.Print("   x")
		for mode := big.ToNearestEven; mode <= big.ToPositiveInf; mode++ {
			fmt.Printf("  %s", mode)
		}
		f64 := 1.6180339887499

		for mode := big.ToNearestEven; mode <= big.ToPositiveInf; mode++ {
			f := new(big.Float).SetPrec(2).SetMode(mode).SetFloat64(f64)
			fmt.Printf("  %*g", len(mode.String()), f)
		}
	*/

	//	fmt.Println("   ")
	//	a := big.NewRat(1, 5)
	//	fmt.Println(a)

	//	fmt.Println(a.FloatString(100))

	//fmt.Println(a.RatString())
	/*
		var i int64
		for i = 2; i < 1001; i++ {
			b := big.NewRat(1, i)
			fmt.Println(b.FloatString(100))
			//fmt.Println(i, b.FloatString(100))
		}
	*/

	var i int

	var max int = 0
	var max_p int = 0
	for i = 1; i < 1001; i++ {
		tmp := CircurLength(i)
		if max < tmp {
			max_p = i
			max = tmp
		}
	}

	fmt.Println(max_p)

}
<commit_msg>update golang<commit_after>package main

import (
	"fmt"
	//	"math/big"
	//	"github.com/fenglyu/projecteuler/golang/common"
)

func CircurLength(n int) int {
	a := 1
	b := n
	c := 0
	t := 0
	hash := make(map[int]int)

	for {
		if hash[a] > 0 {
			break
		}

		hash[a]++
		//		fmt.Println(a, "/", b, "=") //, n)
		a = a % b * 10
		t++
		c++
	}
	/*
		fmt.Println(t - hash[a])
	*/

	return t - hash[a]
	// https://www.xarg.org/puzzle/project-euler/problem-26/
}

func main() {

	/*
		fmt.Print("   x")
		for mode := big.ToNearestEven; mode <= big.ToPositiveInf; mode++ {
			fmt.Printf("  %s", mode)
		}
		f64 := 1.6180339887499

		for mode := big.ToNearestEven; mode <= big.ToPositiveInf; mode++ {
			f := new(big.Float).SetPrec(2).SetMode(mode).SetFloat64(f64)
			fmt.Printf("  %*g", len(mode.String()), f)
		}
	*/

	//	fmt.Println("   ")
	//	a := big.NewRat(1, 5)
	//	fmt.Println(a)

	//	fmt.Println(a.FloatString(100))

	//fmt.Println(a.RatString())
	/*
		var i int64
		for i = 2; i < 1001; i++ {
			b := big.NewRat(1, i)
			fmt.Println(b.FloatString(100))
			//fmt.Println(i, b.FloatString(100))
		}
	*/

	var i int

	var max int = 0
	var max_p int = 0
	for i = 1; i < 1001; i++ {
		tmp := CircurLength(i)
		if max < tmp {
			max_p = i
			max = tmp
		}
	}

	fmt.Println(max_p)

}
<|endoftext|>