Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "bufio"
- "fmt"
- "os"
- "reflect"
- "strconv"
- "strings"
- )
- type provider struct {
- product string
- quantity int
- price float64
- }
- type consumer struct {
- product string
- quantity int
- }
- func main() {
- providers := [][]provider{{}}
- consumers := [][]consumer{{}}
- var providersCh chan [][]provider = make(chan [][]provider)
- var consumersCh chan [][]consumer = make(chan [][]consumer)
- var result chan []provider = make(chan []provider)
- providers, consumers = readFromFile("IFF5-2_ZavadskisD_L3_dat_3.txt")
- go runProcesses(providersCh, consumersCh, result)
- providersCh <- providers
- consumersCh <- consumers
- writeToFile("IFF5-2_ZavadskisD_L3_rez.txt", <-result, providers, consumers)
- }
- func runProcesses(providersCh chan [][]provider, consumersCh chan [][]consumer, result chan []provider) {
- providers := <-providersCh
- consumers := <-consumersCh
- var datap []chan []provider = make([]chan []provider, len(providers)) //provider data input
- for i := range datap {
- datap[i] = make(chan []provider)
- }
- var datac []chan []consumer = make([]chan []consumer, len(consumers)) //consumer data input
- for i := range datac {
- datac[i] = make(chan []consumer)
- }
- var cp []chan provider = make([]chan provider, len(providers)) //provider data output
- for i := range cp {
- cp[i] = make(chan provider)
- }
- var cc []chan consumer = make([]chan consumer, len(consumers)) //consumer data output
- for i := range cc {
- cc[i] = make(chan consumer)
- }
- var jobReqI []chan bool = make([]chan bool, len(consumers)) //consumer job request chanel input
- for i := range jobReqI {
- jobReqI[i] = make(chan bool)
- }
- var jobReqO []chan int = make([]chan int, len(consumers)) //consumer job request chanel output
- for i := range jobReqO {
- jobReqO[i] = make(chan int)
- }
- var cd chan int = make(chan int) //manager data input
- pCnt, cCnt := 0, 0
- go manager(cp, cc, jobReqI, jobReqO, cd, result)
- for i := 0; i < len(providers); i++ {
- go put(cp[i], datap[i])
- datap[i] <- providers[i]
- pCnt += len(providers[i])
- }
- cd <- pCnt
- for i := 0; i < len(consumers); i++ {
- go remove(cc[i], jobReqI[i], jobReqO[i], datac[i])
- datac[i] <- consumers[i]
- cCnt += len(consumers[i])
- }
- cd <- cCnt
- cd <- len(consumers)
- }
- func manager(cp []chan provider, cc []chan consumer, jobReqI []chan bool, jobReqO []chan int, cd chan int, result chan []provider) {
- var b []provider
- var somethingChanged bool
- pCnt := <-cd
- cCnt := <-cd
- jobsCnt := <-cd
- cCntDef := cCnt
- close(cd)
- cases := make([]reflect.SelectCase, len(jobReqI)+len(cp)+len(cc))
- for i, ch := range cp {
- cases[i] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(ch)}
- }
- for i, ch := range cc {
- cases[i+len(cp)] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(ch)}
- }
- for i, ch := range jobReqI {
- cases[i+len(cp)+len(cc)] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(ch)}
- }
- for jobsDone := 0; jobsDone < jobsCnt; {
- chosen, value, ok := reflect.Select(cases)
- fmt.Printf("Value: %v\n", value)
- if ok {
- switch value.Interface().(type) {
- case provider:
- tmp, _ := value.Interface().(provider)
- fmt.Printf("Put: %v\n", value.Interface().(provider))
- b = insertOrUpdate(b, tmp)
- pCnt--
- case consumer:
- tmp, _ := value.Interface().(consumer)
- fmt.Printf("Remove:%v\n", tmp)
- b, somethingChanged = removeOrUpdate(b, tmp)
- if pCnt == 0 && !somethingChanged {
- cCnt--
- } else {
- cCnt = cCntDef
- }
- case bool:
- if pCnt <= 0 && cCnt <= 0 {
- jobReqO[chosen-len(cp)-len(cc)] <- 0
- jobsDone++
- } else {
- jobReqO[chosen-len(cp)-len(cc)] <- 1
- }
- default:
- fmt.Println(chosen)
- fmt.Println(value)
- fmt.Println(value.Interface())
- fmt.Println(reflect.ValueOf(value).Interface())
- panic("dd")
- }
- }
- }
- result <- b
- }
- func put(ch chan provider, data chan []provider) {
- p := <-data
- close(data)
- for i := 0; i < len(p); i++ {
- ch <- p[i]
- }
- close(ch)
- }
- func insertOrUpdate(b []provider, p provider) []provider {
- var i int
- if len(b) == 0 {
- return append(b, p)
- }
- if b[0].product > p.product || b[0].product == p.product && b[0].price > p.price {
- return append([]provider{p}, b...)
- }
- i = len(b) - 1
- if b[i].product < p.product || b[i].product == p.product && b[i].price < p.price {
- return append(b, p)
- }
- for i = 0; i < len(b); i++ {
- if b[i].product == p.product && b[i].price == p.price {
- b[i].quantity += p.quantity
- return b
- }
- if b[i].product > p.product || b[i].product == p.product && b[i].price > p.price {
- return append(b[0:i], append([]provider{p}, b[i:len(b)]...)...)
- }
- }
- return b
- }
- func remove(ch chan consumer, jobReqI chan bool, jobReqO chan int, datac chan []consumer) {
- var jt int
- c := <-datac
- close(datac)
- jobReqI <- true
- for {
- jt = <-jobReqO
- if jt == 0 {
- break
- } else {
- for i := 0; i < len(c); i++ {
- ch <- c[i]
- }
- jobReqI <- true
- }
- }
- close(jobReqI)
- close(jobReqO)
- }
- func removeOrUpdate(b []provider, c consumer) ([]provider, bool) {
- var i int
- if len(b) == 0 {
- return b, false
- }
- for i = 0; i < len(b); i++ {
- if b[i].product == c.product {
- b[i].quantity -= c.quantity
- if b[i].quantity < 0 {
- return append(b[:i], b[i+1:]...), true
- }
- return b, true
- }
- }
- return b, false
- }
- func readFromFile(fileName string) ([][]provider, [][]consumer) {
- var tint int
- var tfloat float64
- file, err := os.Open(fileName)
- check(err)
- defer file.Close()
- scanner := bufio.NewScanner(file)
- //Providers
- scanner.Scan()
- x, err := strconv.Atoi(scanner.Text())
- check(err)
- providers := make([][]provider, x)
- for i := 0; i < x; i++ {
- scanner.Scan()
- y, err := strconv.Atoi(scanner.Text())
- check(err)
- providers[i] = make([]provider, y)
- for j := 0; j < y; j++ {
- scanner.Scan()
- line := strings.Split(scanner.Text(), " ")
- tint, err = strconv.Atoi(line[1])
- check(err)
- tfloat, err = strconv.ParseFloat(line[2], 64)
- check(err)
- providers[i][j] = provider{line[0], tint, tfloat}
- }
- }
- //Consumers
- scanner.Scan()
- x, err = strconv.Atoi(scanner.Text())
- check(err)
- consumers := make([][]consumer, x)
- for i := 0; i < x; i++ {
- scanner.Scan()
- y, err := strconv.Atoi(scanner.Text())
- check(err)
- consumers[i] = make([]consumer, y)
- for j := 0; j < y; j++ {
- scanner.Scan()
- line := strings.Split(scanner.Text(), " ")
- tint, err = strconv.Atoi(line[1])
- check(err)
- consumers[i][j] = consumer{line[0], tint}
- }
- }
- check(scanner.Err())
- return providers, consumers
- }
- func writeToFile(fileName string, final []provider, providers [][]provider, consumers [][]consumer) {
- if _, err := os.Stat(fileName); !os.IsNotExist(err) {
- var err = os.Remove(fileName)
- check(err)
- }
- var file, err = os.Create(fileName)
- check(err)
- defer file.Close()
- f, err := os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY, 0600)
- if err != nil {
- panic(err)
- }
- defer f.Close()
- if _, err = f.WriteString(fmt.Sprintf("%-15s|%-8s|%-8s\n", "Pavadinimas", "Kiekis", "Kaina")); err != nil {
- panic(err)
- }
- for i := 0; i < len(providers); i++ {
- if _, err = f.WriteString(fmt.Sprintf("---------------------------------\n")); err != nil {
- panic(err)
- }
- for j := 0; j < len(providers[i]); j++ {
- if _, err = f.WriteString(fmt.Sprintf("%-15s|%8d|%8.2f\n", providers[i][j].product, providers[i][j].quantity, providers[i][j].price)); err != nil {
- panic(err)
- }
- }
- }
- if _, err = f.WriteString(fmt.Sprintf("---------------------------------\n")); err != nil {
- panic(err)
- }
- if _, err = f.WriteString(fmt.Sprintf("\n\n------------------------\n")); err != nil {
- panic(err)
- }
- if _, err = f.WriteString(fmt.Sprintf("%-15s|%-8s\n", "Pavadinimas", "Kiekis")); err != nil {
- panic(err)
- }
- for i := 0; i < len(consumers); i++ {
- if _, err = f.WriteString(fmt.Sprintf("------------------------\n")); err != nil {
- panic(err)
- }
- for j := 0; j < len(consumers[i]); j++ {
- if _, err = f.WriteString(fmt.Sprintf("%-15s|%8d\n", consumers[i][j].product, consumers[i][j].quantity)); err != nil {
- panic(err)
- }
- }
- }
- if _, err = f.WriteString(fmt.Sprintf("------------------------\n")); err != nil {
- panic(err)
- }
- if _, err = f.WriteString(fmt.Sprintf("\n\n---------------------------------\n")); err != nil {
- panic(err)
- }
- if _, err = f.WriteString(fmt.Sprintf("%-15s|%-8s|%-8s\n", "Pavadinimas", "Kiekis", "Kaina")); err != nil {
- panic(err)
- }
- if _, err = f.WriteString(fmt.Sprintf("---------------------------------\n")); err != nil {
- panic(err)
- }
- for i := 0; i < len(final); i++ {
- if _, err = f.WriteString(fmt.Sprintf("%-15s|%8d|%8.2f\n", final[i].product, final[i].quantity, final[i].price)); err != nil {
- panic(err)
- }
- }
- if _, err = f.WriteString(fmt.Sprintf("---------------------------------\n")); err != nil {
- panic(err)
- }
- }
- func check(e error) {
- if e != nil {
- panic(e)
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement